Ejemplo n.º 1
0
def stdCalc(bmap, count0: int, count50: int, count100: int, count300: int,
            combo: int, mods: int, perfect: int, max_combo: int):
    p = pyt.parser()
    beatmap = p.map(bmap)
    objcount = beatmap.ncircles + beatmap.nsliders + beatmap.nspinners
    totalhits = count50 + count100 + count300
    sr = pyt.diff_calc().calc(beatmap, mods)
    pp, _, _, _, _ = pyt.ppv2(sr.aim,
                              sr.speed,
                              bmap=beatmap,
                              mods=mods,
                              n300=count300,
                              n100=count100,
                              n50=count50,
                              nmiss=count0,
                              combo=combo)
    pp_fc = 0
    if perfect == 0:
        pp_fc, _, _, _, _ = pyt.ppv2(sr.aim,
                                     sr.speed,
                                     bmap=beatmap,
                                     mods=mods,
                                     n300=objcount - totalhits,
                                     n100=count100,
                                     n50=count50,
                                     nmiss=0,
                                     combo=max_combo)
    return round(sr.total, 2), round(pp, 2), round(pp_fc, 2)
Ejemplo n.º 2
0
    def set_embed_pp(
            self,
            mods: Mods = None,
            acc: tuple[Union[float, int]] = (95, 97.5, 100),
    ) -> None:

        if self.mode != 0:
            return

        if not mods:
            mods = self.mods

        self.embed_pp_values = []

        stars = pyttanko.diff_calc().calc(self.mapfile, mods._value_)
        for a in acc:
            n300, n100, n50 = pyttanko.acc_round(a,
                                                 len(self.mapfile.hitobjects),
                                                 0)
            pp = pyttanko.ppv2(
                stars.aim,
                stars.speed,
                n100=n100,
                n50=n50,
                mods=mods._value_,
                bmap=self.mapfile,
                n300=n300,
            )[0]
            self.embed_pp_values.append(f'{a}%-{pp:.2f}PP')
Ejemplo n.º 3
0
    def calculate_score_pp(self, beatmap_id, score):
        p = osu.parser()
        beatmap_url = "https://osu.ppy.sh/osu/{0}".format(beatmap_id)
        beatmap_raw = requests.get(beatmap_url).text
        f = codecs.open(Logic.temp_beatmap_name, "w+", "utf-8")
        f.write(beatmap_raw)
        f.close()
        f = codecs.open(Logic.temp_beatmap_name, encoding="utf-8")
        clean_beatmap = p.map(f)
        f.close()
        os.remove(Logic.temp_beatmap_name)

        stars = osu.diff_calc().calc(
            clean_beatmap, osu.mods_from_str(score.get_mods_string()))

        pp, _, _, _, acc = osu.ppv2(aim_stars=stars.aim,
                                    speed_stars=stars.speed,
                                    bmap=clean_beatmap,
                                    mods=osu.mods_from_str(
                                        score.get_mods_string()),
                                    combo=score.max_combo,
                                    n300=score.number_300s,
                                    n100=score.number_100s,
                                    n50=score.number_50s,
                                    nmiss=score.misses)
        return pp, acc
Ejemplo n.º 4
0
def run():
    ERROR_MARGIN = 0.02
    '''pp can be off by +- 2%
    margin is actually 3x for < 100pp, 2x for 100-200,
    1.5x for 200-300'''

    p = pyttanko.parser()
    bmap = pyttanko.beatmap()
    stars = pyttanko.diff_calc()

    try:
        for s in suite.suite:
            print_score(s)

            with open("test/test_suite/%d.osu" % (s.id), "r") as f:
                p.map(f, bmap=bmap)

            stars.calc(bmap, s.mods)
            pp, _, _, _, _ = pyttanko.ppv2(stars.aim,
                                           stars.speed,
                                           bmap=bmap,
                                           mods=s.mods,
                                           n300=s.n300,
                                           n100=s.n100,
                                           n50=s.n50,
                                           nmiss=s.nmiss,
                                           combo=s.max_combo)

            margin = s.pp * ERROR_MARGIN

            if s.pp < 100:
                margin *= 3
            elif s.pp < 200:
                margin *= 2
            elif s.pp < 300:
                margin *= 1.5

            if abs(pp - s.pp) >= margin:
                pyttanko.info("failed test: got %gpp, expected %g\n" %
                              (pp, s.pp))

                exit(1)

    except KeyboardInterrupt:
        pass

    except FileNotFoundError:
        pyttanko.info("please download the test suite by running " +
                      "./download_suite\n")
        sys.exit(1)

    except Exception as e:
        if p.done:
            raise
        else:
            pyttanko.info("%s\n%s\n" % (traceback.format_exc(), str(p)))

        sys.exit(1)
Ejemplo n.º 5
0
 async def calculate_pp(self, stars, bmap, mods, n50, n100, n300, combo, misses):
     calc = pyttanko.ppv2(stars['aim'], stars['speed'], max_combo=bmap.max_combo,
                          nsliders=bmap.count_slider, ncircles=bmap.count_normal,
                          nobjects=(bmap.count_slider + bmap.count_normal + bmap.count_spinner),
                          base_ar=bmap.diff_approach, base_od=bmap.diff_overall,
                          mods=mods, n50=n50,
                          n100=n100, n300=n300, combo=combo, nmiss=misses)
     pp = round(calc[0], 2)
     return pp
Ejemplo n.º 6
0
 def get_real_pp(self):
     stars = pyttanko.diff_calc().calc(self.bmap, self.mods)
     ppv2 = pyttanko.ppv2(aim_stars=stars.aim,
                          speed_stars=stars.speed,
                          mods=self.mods,
                          n100=self.count100,
                          n50=self.count50,
                          n300=self.count300,
                          nmiss=self.misses,
                          combo=self.combo,
                          bmap=self.bmap)
     return round(ppv2[0], 2)
Ejemplo n.º 7
0
    def calculate_osu_pp(self, osu_file, mods=0):
        """
        计算pp
        :param osu_file:    file osu后缀名的文件
        :param mods:        int 模式 HR HD DT NF等,可调用api进行查看
        :param n300:        int 300
        :param n100:        int 100
        :param n50:         int 50
        :param nmiss:       int miss
        :param combo:       int 最大的连击数
        :return:            (str stars星级, str pp点)
        """
        p = osu.parser()
        with open(osu_file, "r", encoding="utf-8") as f:
            bmap = p.map(f)

        stars = osu.diff_calc().calc(bmap)
        if self.is_search_map is True:
            pp, _, _, _, _ = osu.ppv2(stars.aim,
                                      stars.speed,
                                      bmap=bmap,
                                      mods=mods)
        else:
            pp, _, _, _, _ = osu.ppv2(stars.aim,
                                      stars.speed,
                                      bmap=bmap,
                                      mods=self.int_mods,
                                      n300=self.count300,
                                      n100=self.count100,
                                      n50=self.count50,
                                      nmiss=self.countmiss,
                                      combo=self.maxcombo)

        # pp, _, _, _, _ = osu.ppv2(
        #     stars.aim, stars.speed, bmap=bmap, mods=mods,
        #     n300=n300, n100=n100, n50=n50, nmiss=nmiss,
        #     combo=combo
        # )
        return "{:.1f}".format(stars.total), "{}".format(int(pp))
Ejemplo n.º 8
0
def calc_if(osufile, mods_num, c50, c100, mapcb):
    p = osu.parser()
    with open(osufile, 'r', encoding='utf-8') as f:
        bmap = p.map(f)

    stars = osu.diff_calc().calc(bmap, mods_num)

    pp = osu.ppv2(
        stars.aim, stars.speed, mods=mods_num,
        n100=c100, n50=c50, nmiss=0, max_combo=mapcb, bmap=bmap
    )

    return pp[0]
Ejemplo n.º 9
0
 def get_if_fc_pp(self):
     # Set miss count to zero
     self.misses = 0
     self.combo = self.bmap.max_combo()
     stars = pyttanko.diff_calc().calc(self.bmap, self.mods)
     # max_combo used if combo is not provided =>
     # don't need to set it manually
     ppv2 = pyttanko.ppv2(stars.aim,
                          stars.speed,
                          n100=self.count100,
                          n50=self.count50,
                          n300=self.count300,
                          mods=self.mods,
                          bmap=self.bmap)
     return round(ppv2[0], 2)
Ejemplo n.º 10
0
def ppCalc(mapId, modsInt, n300, n100, n50):
    bmap = beatmapsDataParser().bmapData(mapId, modsInt)
    pp, _, _, _, _ = osu.ppv2(aim_stars=bmap["aim"],
                              speed_stars=bmap["speed"],
                              max_combo=bmap["maxcombo"],
                              nsliders=bmap["nsliders"],
                              ncircles=bmap["ncircles"],
                              nobjects=bmap["nobjects"],
                              base_ar=bmap["ar"],
                              base_od=bmap["od"],
                              mods=modsInt,
                              n300=n300,
                              n100=n100,
                              n50=n50)
    return float("%.2f" % pp)
Ejemplo n.º 11
0
    def pp_if_fc(self) -> tuple[float, float]:
        if self.mode != 0:
            return

        n100 = round(self.n100 / 1.5)
        n50 = round(self.n50 / 1.5)
        stars = pyttanko.diff_calc().calc(self.bmap.mapfile, self.mods._value_)
        data = pyttanko.ppv2(stars.aim,
                             stars.speed,
                             bmap=self.bmap.mapfile,
                             mods=self.mods._value_,
                             n100=n100,
                             n50=n50)

        return data[0], data[4]
Ejemplo n.º 12
0
def calc_acc_pp(osufile, mods_num):
    acc_pp = []
    p = osu.parser()
    with open(osufile, 'r', encoding='utf-8') as f:
        bmap = p.map(f)

    stars = osu.diff_calc().calc(bmap, mods_num)
    for acc in range(95, 101):
        c300, c100, c50 = osu.acc_round(acc, len(bmap.hitobjects), 0)

        pp, _, _, _, _ = osu.ppv2(
            stars.aim, stars.speed, mods=mods_num,
            n300=c300, n100=c100, n50=c50, bmap=bmap
        )

        acc_pp.append(int(pp))
        
    return acc_pp
Ejemplo n.º 13
0
def std(map_id, beatmap, mods, combo, n300, n100, n50, nmiss):
    """Get pp for a Standard play."""
    if not beatmap["text"]:
        return None
    parser = pyttanko.parser()
    with io.StringIO(beatmap["text"]) as f:
        bmap = parser.map(f)
    stars = pyttanko.diff_calc().calc(bmap, mods)
    return pyttanko.ppv2(
        aim_stars=stars.aim,
        speed_stars=stars.speed,
        mods=mods,
        combo=combo,
        n300=n300,
        n100=n100,
        n50=n50,
        nmiss=nmiss,
        bmap=bmap,
    )[0]
Ejemplo n.º 14
0
def calc_pp(osufile, mods_num, maxcb, c50, c100, c300, miss):
    p = osu.parser()
    with open(osufile, 'r', encoding='utf-8') as f:
        bmap = p.map(f)

    stars = osu.diff_calc().calc(bmap, mods_num)
    map_stars = stars.total

    pp, aim, speed, acc, accuracy = osu.ppv2(
        stars.aim, stars.speed, mods=mods_num,
        combo=maxcb, n300=c300, n100=c100, n50=c50, nmiss=miss, bmap=bmap
    )

    cs = bmap.cs
    ar = bmap.ar
    od = bmap.od
    hp = bmap.hp
    play_pp = int(round(pp, 2))
    aim_pp = int(round(aim, 2))
    speed_pp = int(round(speed, 2))
    acc_pp = int(round(acc, 2))
    accuracy = round(accuracy, 2)

    return map_stars, cs, ar, od, hp, play_pp, aim_pp, speed_pp, acc_pp, accuracy
Ejemplo n.º 15
0
    async def get_pyttanko(self,
                           map_id: str,
                           accs=[100],
                           mods=0,
                           misses=0,
                           combo=None,
                           completion=None,
                           fc=None):
        url = 'https://osu.ppy.sh/osu/{}'.format(map_id)
        file_path = os.getcwd() + '/temp/{}.osu'.format(map_id)
        await self.download_file(url, file_path)
        bmap = pyttanko.parser().map(open(file_path))
        _, ar, od, cs, hp = pyttanko.mods_apply(mods,
                                                ar=bmap.ar,
                                                od=bmap.od,
                                                cs=bmap.cs,
                                                hp=bmap.hp)
        stars = pyttanko.diff_calc().calc(bmap, mods=mods)
        bmap.stars = stars.total
        bmap.aim_stars = stars.aim
        bmap.speed_stars = stars.speed

        if not combo:
            combo = bmap.max_combo()

        bmap.pp = []
        bmap.aim_pp = []
        bmap.speed_pp = []
        bmap.acc_pp = []

        bmap.acc = accs

        for acc in accs:
            n300, n100, n50 = pyttanko.acc_round(acc, len(bmap.hitobjects),
                                                 misses)
            pp, aim_pp, speed_pp, acc_pp, _ = pyttanko.ppv2(bmap.aim_stars,
                                                            bmap.speed_stars,
                                                            bmap=bmap,
                                                            mods=mods,
                                                            n300=n300,
                                                            n100=n100,
                                                            n50=n50,
                                                            nmiss=misses,
                                                            combo=combo)
            bmap.pp.append(pp)
            bmap.aim_pp.append(aim_pp)
            bmap.speed_pp.append(speed_pp)
            bmap.acc_pp.append(acc_pp)
        if fc:
            n300, n100, n50 = pyttanko.acc_round(fc, len(bmap.hitobjects), 0)
            # print("-------------", n300, n100, n50)
            fc_pp, _, _, _, _ = pyttanko.ppv2(bmap.aim_stars,
                                              bmap.speed_stars,
                                              bmap=bmap,
                                              mods=mods,
                                              n300=n300 + misses,
                                              n100=n100,
                                              n50=n50,
                                              nmiss=0,
                                              combo=bmap.max_combo())

        pyttanko_json = {
            'version': bmap.version,
            'title': bmap.title,
            'artist': bmap.artist,
            'creator': bmap.creator,
            'combo': combo,
            'max_combo': bmap.max_combo(),
            'misses': misses,
            'mode': bmap.mode,
            'stars': bmap.stars,
            'aim_stars': bmap.aim_stars,
            'speed_stars': bmap.speed_stars,
            'pp': bmap.pp,  # list
            'aim_pp': bmap.aim_pp,
            'speed_pp': bmap.speed_pp,
            'acc_pp': bmap.acc_pp,
            'acc': bmap.acc,  # list
            'cs': cs,
            'od': od,
            'ar': ar,
            'hp': hp
        }

        if completion:
            try:
                pyttanko_json['map_completion'] = (completion /
                                                   len(bmap.hitobjects)) * 100
            except:
                pyttanko_json['map_completion'] = "Error"

        os.remove(file_path)
        return pyttanko_json
Ejemplo n.º 16
0
def calculatePlay(bmap,
                  mode: int = 0,
                  count0: int = 0,
                  count50: int = 0,
                  count100: int = 0,
                  count300: int = 0,
                  countgeki: int = 0,
                  countkatu: int = 0,
                  combo: int = 0,
                  mods: int = 0,
                  perfect: int = 0,
                  calcPP: int = 1):

    if mode == 0:
        #Standard

        modString = pyt.mods_str(mods)
        accuracy = acc.stdCalc(count0, count50, count100, count300)
        p = pyt.parser()
        beatmap = p.map(bmap)
        objcount = beatmap.ncircles + beatmap.nsliders + beatmap.nspinners
        totalhits = count50 + count100 + count0
        sr = pyt.diff_calc().calc(beatmap, mods)
        pp = 0
        if calcPP == 1:
            pp, _, _, _, _ = pyt.ppv2(sr.aim,
                                      sr.speed,
                                      bmap=beatmap,
                                      mods=mods,
                                      n300=count300,
                                      n100=count100,
                                      n50=count50,
                                      nmiss=count0,
                                      combo=combo)
        pp_fc = 0
        if perfect == 0:
            pp_fc, _, _, _, _ = pyt.ppv2(sr.aim,
                                         sr.speed,
                                         bmap=beatmap,
                                         mods=mods,
                                         n300=objcount - totalhits,
                                         n100=count100,
                                         n50=count50,
                                         nmiss=0,
                                         combo=beatmap.max_combo())
            accuracy_fc = acc.stdCalc(0, count50, count100,
                                      objcount - totalhits)

        beatmapDict = {
            "title": beatmap.title,
            "artist": beatmap.artist,
            "creator": beatmap.creator,
            "version": beatmap.version,
            "objcount": objcount,
            "mode": beatmap.mode,
            "maxcombo": beatmap.max_combo()
        }

        playDict = {
            "totalhits": totalhits + count0,
            "pp": round(pp, 2),
            "pp_fc": round(pp_fc, 2),
            "accuracy": accuracy,
            "accuracy_fc": 0 if perfect == 1 else accuracy_fc,
            "modString": modString if modString != "nomod" else "NM",
            "rating": round(sr.total, 2),
            "completion": round(((totalhits + count300) * 100) / objcount, 2),
            "mode_icon": "https://i.imgur.com/lT2nqls.png",
            "mode_name": "Standard"
        }

    elif mode == 1:
        #Taiko

        p = pyt.parser()
        beatmap = p.map(bmap)
        beatmapDict = {
            "title": beatmap.title,
            "artist": beatmap.artist,
            "creator": beatmap.creator,
            "version": beatmap.version,
            "objcount": 0,
            "mode": beatmap.mode,
            "maxcombo": None
        }

        playDict = {
            "totalhits":
            0,
            "pp":
            "Not implemented.",
            "pp_fc":
            0,
            "accuracy":
            acc.taikoCalc(count0, count100, count300),
            "accuracy_fc":
            0 if perfect == 1 else acc.taikoCalc(0, count100, count300 +
                                                 count0),
            "modString":
            modString if modString != "nomod" else "NM",
            "rating":
            "N/A",
            "completion":
            100,
            "mode_icon":
            "https://i.imgur.com/G6bzM0X.png",
            "mode_name":
            "Taiko"
        }

    elif mode == 2:
        #CTB

        accuracy = acc.ctbCalc(count0, countkatu, count50, count100, count300)
        beatmap = Beatmap(bmap)
        p = pyt.parser()
        beatmapMetadata = p.map(bmap)
        difficulty = Difficulty(beatmap, mods)
        pp = 0
        if calcPP == 1:
            pp = round(calculate_pp(difficulty, accuracy, combo, count0), 2)
        beatmapDict = {
            "title": beatmapMetadata.title,
            "artist": beatmapMetadata.artist,
            "creator": beatmapMetadata.creator,
            "version": beatmapMetadata.version,
            "objcount": len(beatmap.hitobjects),
            "mode": beatmapMetadata.mode,
            "maxcombo": beatmap.max_combo
        }
        playDict = {
            "totalhits": 0,
            "pp": pp,
            "pp_fc": 0,
            "accuracy": accuracy,
            "accuracy_fc": 0,
            "modString": modString if modString != "nomod" else "NM",
            "rating": round(difficulty.star_rating, 2),
            "completion": 100,
            "mode_icon": "https://i.imgur.com/EsanYkH.png",
            "mode_name": "Catch the Beat"
        }

    elif mode == 3:
        #Mania

        p = pyt.parser()
        beatmap = p.map(bmap)
        beatmapDict = {
            "title": beatmap.title,
            "artist": beatmap.artist,
            "creator": beatmap.creator,
            "version": beatmap.version,
            "objcount": 0,
            "mode": beatmap.mode,
            "maxcombo": None
        }

        playDict = {
            "totalhits":
            0,
            "pp":
            "Not implemented.",
            "pp_fc":
            0,
            "accuracy":
            acc.maniaCalc(count0, count50, count100, countkatu, count300,
                          countgeki),
            "accuracy_fc":
            0,
            "modString":
            modString if modString != "nomod" else "NM",
            "rating":
            "N/A",
            "completion":
            100,
            "mode_icon":
            "https://i.imgur.com/0uZM1PZ.png",
            "mode_name":
            "Mania"
        }

    return beatmapDict, playDict
Ejemplo n.º 17
0
def display_play(api_link, api_key, response, response_number=0, mode=0):
    try:
        beatmap_info = requests.get(
            f'{api_link}get_beatmaps?k={api_key}&b={response.json()[response_number]["beatmap_id"]}&m={mode}'
        )
        beatmap_info.json()[0]
    except IndexError:
        beatmap_info = requests.get(
            f'{api_link}get_beatmaps?k={api_key}&b={response.json()[response_number]["beatmap_id"]}&m={mode}&a=1'
        )

    with open(image_data) as file:
        data = json.load(file)

    img = Image.new('RGBA', (900, 500), color=(0, 0, 0, 255))
    black = Image.new('RGBA', (900, 500), color=(0, 0, 0, 0))

    total_count = int(beatmap_info.json()[0]["count_normal"]) + int(
        beatmap_info.json()[0]["count_slider"]) + int(
            beatmap_info.json()[0]["count_spinner"])
    accuracy = int(response.json()[response_number]["count300"]) + int(
        response.json()[response_number]["count100"]) * (1 / 3) + int(
            response.json()[response_number]["count50"]) * (1 / 6)
    count_sum = int(response.json()[response_number]["count300"]) + int(
        response.json()[response_number]["count100"]) + int(
            response.json()[response_number]["count50"]) + int(
                response.json()[response_number]["countmiss"])

    completion = count_sum / total_count

    try:
        beatmap_cover = Image.open(
            requests.get(
                f'https://assets.ppy.sh/beatmaps/{beatmap_info.json()[0]["beatmapset_id"]}/covers/cover.jpg',
                stream=True).raw)
    except UnidentifiedImageError:
        beatmap_cover = Image.new('RGBA', (900, 500), color=(0, 0, 0, 0))

    mod_list = [
        'NF', 'EZ', 'TD', 'HD', 'HR', 'SD', 'DT', '', 'HT', 'NC', 'FL', '',
        'SO', '', 'PF', '', '', '', '', '', 'FI', '', '', '', '', '', '', '',
        '', '', 'MR'
    ]
    rank_colors = {
        'F': (242, 56, 56),
        'D': (242, 56, 56),
        'C': (119, 57, 189),
        'B': (57, 111, 244),
        'A': (72, 248, 80),
        'S': (245, 225, 90),
        'X': (255, 223, 6),
        'SH': (170, 183, 204),
        'XH': (170, 183, 204)
    }
    mod_values = {'EZ': 2, 'HR': 16, 'DT': 64, 'NC': 64, 'HT': 256}

    pt35_light = ImageFont.truetype(lemon_milk_light, 35)
    pt30_light = ImageFont.truetype(lemon_milk_light, 30)
    pt25_light = ImageFont.truetype(lemon_milk_light, 25)
    pt20_light = ImageFont.truetype(lemon_milk_light, 20)

    pt200_regular = ImageFont.truetype(lemon_milk_regular, 200)
    pt50_regular = ImageFont.truetype(lemon_milk_regular, 50)
    pt35_regular = ImageFont.truetype(lemon_milk_regular, 35)

    special = ImageFont.truetype(special_characters, 25)

    beatmap_cover = beatmap_cover.resize((900, 250))
    beatmap_cover = beatmap_cover.convert('RGBA')

    black_draw = ImageDraw.Draw(black)
    black_draw.rectangle(((0, 0), (900, 500)), fill=(0, 0, 0, 127))

    img.paste(beatmap_cover, (0, 0))
    img = Image.alpha_composite(img, black)

    draw = ImageDraw.Draw(img)
    draw.polygon(([0, 100, 900, 200, 900, 500, 0, 500]), fill=(47, 49, 54))
    draw.line([(0, 100), (900, 200)], fill=(102, 104, 110), width=6)

    #--------------------   HEADER   --------------------#
    if len(beatmap_info.json()[0]["version"]) >= 15:
        version = beatmap_info.json()[0]["version"][:15] + '...'

    else:
        version = beatmap_info.json()[0]["version"]

    if len(beatmap_info.json()[0]["title"]) >= 22:
        title = beatmap_info.json()[0]["title"][:22] + '...'

    else:
        title = beatmap_info.json()[0]["title"]

    draw.text((28, 18), f'{title}', fill=(255, 255, 255), font=pt35_light)
    draw.text((30, 55),
              f'{beatmap_info.json()[0]["creator"]}',
              fill=(255, 255, 255),
              font=pt20_light)
    draw.text((875, 28),
              f'[{version}]',
              fill=(255, 255, 255),
              font=pt30_light,
              anchor='rt')
    draw.text((875, 70), '★', fill=(255, 255, 255), font=special, anchor='rt')

    #--------------------   SCORES LEFT   --------------------#
    draw.text((28, 150),
              f'{" ".join(response.json()[response_number]["score"])}',
              fill=(255, 255, 255),
              font=pt50_regular)

    draw.rectangle([(30, 220), (135, 260)], fill=(57, 111, 244))
    draw.text((85, 227),
              '300',
              fill=(47, 49, 54),
              font=pt35_regular,
              anchor='mt')
    draw.text((155, 227),
              f'{response.json()[response_number]["count300"]}',
              fill=(255, 255, 255),
              font=pt35_light,
              anchor='lt')

    draw.rectangle([(30, 268), (135, 308)], fill=(72, 248, 80))
    draw.text((85, 275),
              '100',
              fill=(47, 49, 54),
              font=pt35_regular,
              anchor='mt')
    draw.text((155, 275),
              f'{response.json()[response_number]["count100"]}',
              fill=(255, 255, 255),
              font=pt35_light,
              anchor='lt')

    draw.rectangle([(30, 316), (135, 356)], fill=(245, 225, 90))
    draw.text((85, 323),
              '50',
              fill=(47, 49, 54),
              font=pt35_regular,
              anchor='mt')
    draw.text((155, 323),
              f'{response.json()[response_number]["count50"]}',
              fill=(255, 255, 255),
              font=pt35_light,
              anchor='lt')

    draw.rectangle([(30, 364), (135, 404)], fill=(242, 56, 56))
    draw.text((85, 371),
              'miss',
              fill=(47, 49, 54),
              font=pt35_regular,
              anchor='mt')
    draw.text((155, 371),
              f'{response.json()[response_number]["countmiss"]}',
              fill=(255, 255, 255),
              font=pt35_light,
              anchor='lt')

    #--------------------   SCORES RIGHT   --------------------#
    draw.text((500, 227),
              'accuracy:',
              fill=(255, 255, 255),
              font=pt35_light,
              anchor='rt')
    draw.text((510, 227),
              f'{round(accuracy/count_sum*100, 2)}%',
              fill=(142, 142, 142),
              font=pt35_light,
              anchor='lt')

    draw.text((500, 275),
              'combo:',
              fill=(255, 255, 255),
              font=pt35_light,
              anchor='rt')
    draw.text(
        (520, 275),
        f'{response.json()[response_number]["maxcombo"]}/{beatmap_info.json()[0]["max_combo"]}',
        fill=(142, 142, 142),
        font=pt35_light,
        anchor='lt')
    draw.text((505, 290), 'x', fill=(142, 142, 142), font=special, anchor='lt')

    if 'H' in response.json()[response_number]["rank"]:
        rank = response.json()[response_number]["rank"][:-1]
    else:
        rank = response.json()[response_number]["rank"]

    if 'X' in response.json()[response_number]["rank"]:
        rank = 'SS'

    draw.text((800, 250),
              f'{rank}',
              fill=rank_colors[response.json()[response_number]["rank"]],
              font=pt200_regular,
              anchor='mt')

    if count_sum != total_count:
        draw.text((30, 458),
                  '.',
                  fill=(255, 255, 255),
                  font=pt50_regular,
                  anchor='lt')
        draw.text((50, 450),
                  f'completion: {round(completion*100, 2)}%',
                  fill=(142, 142, 142),
                  font=pt25_light,
                  anchor='lt')

    draw.text((870, 458),
              f'{response.json()[response_number]["date"]}',
              fill=(142, 142, 142),
              font=pt25_light,
              anchor='rt')

    mod_code = int(response.json()[response_number]['enabled_mods'])
    mod_code = list(bin(mod_code)[2:])
    mod_code.reverse()

    if len(mod_code) == 1 and mod_code[0] == '0':
        mods = [Image.fromarray(np.array(data['NM'], dtype=np.uint8))]
    else:
        mods = [
            Image.fromarray(np.array(data[mod_list[x]], dtype=np.uint8))
            for x in range(len(mod_code)) if mod_code[x] == '1'
        ]

    mod_request = [
        mod_list[x] for x in range(len(mod_code)) if mod_code[x] == '1'
    ]

    if ('SD' in mods) and ('PF' in mods):
        mods.remove(Image.fromarray(np.array(data['SD'], dtype=np.uint8)))
    if ('DT' in mod_request) and ('NC' in mod_request):
        mod_request.remove('DT')
        mods.remove(Image.fromarray(np.array(data['DT'], dtype=np.uint8)))

    if any(item in ['EZ', 'HR', 'DT', 'NC', 'HT'] for item in mod_request):
        mod_request = sum([
            mod_values[x] for x in mod_request
            if x in ['EZ', 'HR', 'DT', 'NC', 'HT']
        ])
        try:
            beatmap_info = requests.get(
                f'{api_link}get_beatmaps?k={api_key}&b={response.json()[response_number]["beatmap_id"]}&mods={mod_request}&m={mode}'
            )
            beatmap_info.json()[0]
        except IndexError:
            beatmap_info = requests.get(
                f'{api_link}get_beatmaps?k={api_key}&b={response.json()[response_number]["beatmap_id"]}&mods={mod_request}&m={mode}&a=1'
            )

    draw.text((850, 70),
              f'{round(float(beatmap_info.json()[0]["difficultyrating"]),2)}',
              fill=(255, 255, 255),
              font=pt25_light,
              anchor='rt')

    if response_number == 0:
        try:
            pp, _, _, _, _ = osu.ppv2(
                aim_stars=float(beatmap_info.json()[0]["diff_aim"]),
                speed_stars=float(beatmap_info.json()[0]["diff_speed"]),
                max_combo=int(beatmap_info.json()[0]["max_combo"]) *
                completion,
                nsliders=int(beatmap_info.json()[0]["count_slider"]) *
                completion,
                ncircles=int(beatmap_info.json()[0]["count_normal"]) *
                completion,
                nobjects=int(beatmap_info.json()[0]["count_spinner"]) *
                completion,
                base_ar=float(beatmap_info.json()[0]["diff_approach"]),
                base_od=float(beatmap_info.json()[0]["diff_overall"]),
                mode=int(beatmap_info.json()[0]["mode"]),
                mods=int(response.json()[response_number]["enabled_mods"]),
                combo=int(response.json()[response_number]["maxcombo"]),
                n300=int(response.json()[response_number]["count300"]),
                n100=int(response.json()[response_number]["count100"]),
                n50=int(response.json()[response_number]["count50"]),
                nmiss=int(response.json()[response_number]["countmiss"]),
                score_version=1)
            pp = round(pp, 2)

        except TypeError:
            pp = 'NaN'

    else:
        pp = round(float(response.json()[response_number]["pp"]), 2)

    try:
        fc_pp, _, _, _, _ = osu.ppv2(
            aim_stars=float(beatmap_info.json()[0]["diff_aim"]),
            speed_stars=float(beatmap_info.json()[0]["diff_speed"]),
            max_combo=int(beatmap_info.json()[0]["max_combo"]),
            nsliders=int(beatmap_info.json()[0]["count_slider"]),
            ncircles=int(beatmap_info.json()[0]["count_normal"]),
            nobjects=int(beatmap_info.json()[0]["count_spinner"]),
            base_ar=float(beatmap_info.json()[0]["diff_approach"]),
            base_od=float(beatmap_info.json()[0]["diff_overall"]),
            mode=int(beatmap_info.json()[0]["mode"]),
            mods=int(response.json()[response_number]["enabled_mods"]),
            combo=int(beatmap_info.json()[0]["max_combo"]),
            n300=int(response.json()[response_number]["count300"]) +
            int(response.json()[response_number]["countmiss"]),
            n100=int(response.json()[response_number]["count100"]),
            n50=int(response.json()[response_number]["count50"]),
            nmiss=0,
            score_version=1)
        fc_pp = round(fc_pp, 2)

    except TypeError:
        fc_pp = 'NaN'

    draw.text((500, 323),
              'pp:',
              fill=(255, 255, 255),
              font=pt35_light,
              anchor='rt')
    draw.text((510, 323),
              f'{pp}',
              fill=(142, 142, 142),
              font=pt35_light,
              anchor='lt')

    draw.text((875, 112),
              'pp',
              fill=(255, 255, 255),
              font=pt25_light,
              anchor='rt')
    draw.text((840, 112),
              f'{fc_pp}',
              fill=(255, 255, 255),
              font=pt25_light,
              anchor='rt')

    mod_bg = Image.new('RGBA', (len(mods) * 71, 50), color=(47, 49, 54, 255))
    a = Image.new('RGBA', (len(mods) * 71, 50), color=(47, 49, 54, 255))

    [a.paste(mods[x].resize((71, 50)), (71 * x, 0)) for x in range(len(mods))]

    a = Image.alpha_composite(mod_bg, a)

    if len(mods) == 7:
        img.paste(a, (218, 355))
    else:
        img.paste(a, (290, 355))

    return img