peace-performance (Rust) binding for python. To calculate star ratings and performance points for all osu! gamemodes

Overview

peace-performance-python

Fast, To calculate star ratings and performance points for all osu! gamemodes

peace-performance (Rust) binding for python based on PyO3.

Cross-platform support.

Faster than oppai-ng, see the benchmark for details.

Note: This library is not currently uploaded to PypI, you may need to download it locally for compilation and then import it in python.

Minimal Examples

from peace_performance_python.prelude import *

beatmap = await Beatmap.create('path_to_osu_file') # Beatmap can be cached and reused!
result = Calculator(acc=98.8, miss=3).calculate(beatmap) # Calculator can also

Full Examples

import asyncio
import sys

# import all
from peace_performance_python.prelude import *
# or
# from peace_performance_python.beatmap import Beatmap
# from peace_performance_python.calculator import Calculator

from tests import join_beatmap, HITORIGOTO


# Initial Rust logger (optional)
set_log_level('trace')
init_logger()


# Choose a style you like
def calculate_1(beatmap: Beatmap) -> CalcResult:
    return calculate_pp(beatmap, Calculator({'acc': 98.8, 'miss': 3}))


def calculate_2(beatmap: Beatmap) -> CalcResult:
    # --
    c = Calculator()
    c.set_acc(98.8)
    c.set_miss(3)

    # or
    c.acc = 98.8
    c.miss = 3

    # or
    c.setattr('acc', 98.8)
    c.setattr('miss', 3)
    return calculate_pp(beatmap, c)


def calculate_3(beatmap: Beatmap) -> CalcResult:
    c = Calculator()
    c.set_with_dict({'acc': 98.8, 'miss': 3})
    return calculate_pp(beatmap, c)


def calculate_4(beatmap: Beatmap) -> CalcResult:
    return Calculator({'acc': 98.8, 'miss': 3}).calculate(beatmap)


def calculate_5(beatmap: Beatmap) -> CalcResult:
    return Calculator(acc=98.8, miss=3).calculate(beatmap)


async def main():
    path = join_beatmap(HITORIGOTO)
    # Load beatmap
    beatmap = await Beatmap.create(path)
    # Calculate pp
    result = calculate_5(beatmap)
    print('\n***** result:', result)
    print('\n***** result.pp:', result.pp)
    print('\n***** result as dict:', result.attrs_dict)
    print('\n***** result.raw_stars as dict:', result.raw_stars.attrs_dict)
    print('\n***** result.raw_pp as dict:', result.raw_pp.attrs_dict)

if __name__ == '__main__':
    asyncio.run(main())

Running results

 TRACE peace_performance_python::methods::common > function=async_read_file duration=289.1µs
 TRACE peace_performance_python::methods::pp     > function=async_parse_beatmap duration=414µs
 TRACE peace_performance_python::methods::pp     > function=calc_with_any_pp duration=99.6µs
 TRACE peace_performance_python::objects::calculator > function=calc duration=245.4µs

...

***** result.pp: 152.19204711914062

...

***** result as dict: {
    'mode': 0, 
    'mods': 0, 
    'pp': 152.19204711914062, 
    'stars': 5.162832260131836, 
    'raw_pp': {
        'aim': 73.0337905883789, 
        'spd': 31.048368453979492, 
        'str': None, 
        'acc': 45.17241287231445, 
        'total': 152.19204711914062}, 
    'raw_stars': {
        'stars': 5.162832260131836, 
        'max_combo': 476, 
        'ar': 9.0, 
        'n_fruits': None, 
        'n_droplets': None, 
        'n_tiny_droplets': None, 
        'od': 8.5, 
        'speed_strain': 2.0723509788513184, 
        'aim_strain': 2.7511043548583984, 
        'n_circles': 207, 
        'n_spinners': 1
        }
    }

...

Building

This package is intended to be built using rust, maturin or setuptools_rust.

1. Install Rust

posix

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

windows

https://static.rust-lang.org/rustup/dist/x86_64-pc-windows-msvc/rustup-init.exe

2. Install python dev dependencies

pip install -r requirements-dev.txt

3. Build native python lib

maturin develop --release

OR

python setup.py develop

Compile to .whl to use pip installation

maturin build --release

OR

python setup.py bdist_wheel

install .whl

# maturin build
pip install target/wheels/<name>.whl

# setup.py build
pip install dist/<name>.whl

Run tests and benchmarks

Once built, you can run the tests and benchmakrs using pytest

pytest

or bench and draw a image

pytest --benchmark-histogram

Run examples

python examples.py

Vs Oppai-ng

peace-performance Python bindings vs C89 oppai-ng.

Fast than oppai, the longer the map, the more obvious the advantages of rust.

peace-performance enables the no_sliders_no_leniency feature to be consistent with oppai's algorithm (faster, but loses precision).

If you need maximum precision (osu-performance) rather than performance, use all_included features.

------------------------------------------------------------------------ benchmark 'bench-oppai-vs-rust': 12 tests -------------------------------------------------------------------------
Name (time in ms)               Min                Max               Mean            StdDev             Median               IQR            Outliers       OPS            Rounds  Iterations
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test_rust_padoru             1.7768 (1.0)       1.9478 (1.0)       1.8508 (1.0)      0.0400 (1.0)       1.8443 (1.0)      0.0535 (1.0)          28;0  540.3156 (1.0)          87           1
test_oppai_padoru            1.8122 (1.02)      9.7861 (5.02)      1.9889 (1.07)     0.5237 (13.08)     1.9249 (1.04)     0.1314 (2.46)          7;8  502.7874 (0.93)        242           1
test_rust_hitorigoto         2.0610 (1.16)      2.5040 (1.29)      2.1910 (1.18)     0.0657 (1.64)      2.1785 (1.18)     0.0694 (1.30)        95;19  456.4104 (0.84)        418           1
test_oppai_hitorigoto        2.5288 (1.42)      3.7520 (1.93)      2.7401 (1.48)     0.1818 (4.54)      2.7067 (1.47)     0.1176 (2.20)        25;17  364.9477 (0.68)        322           1
test_rust_freedom_dive       3.8093 (2.14)      7.3134 (3.75)      3.9828 (2.15)     0.2293 (5.73)      3.9567 (2.15)     0.0845 (1.58)          4;6  251.0782 (0.46)        241           1
test_rust_sotarks            4.4968 (2.53)      5.1071 (2.62)      4.6848 (2.53)     0.0985 (2.46)      4.6712 (2.53)     0.0965 (1.80)        45;13  213.4562 (0.40)        196           1
test_oppai_freedom_dive      5.6872 (3.20)      7.0520 (3.62)      5.9250 (3.20)     0.2010 (5.02)      5.8822 (3.19)     0.1848 (3.46)         17;7  168.7767 (0.31)        159           1
test_oppai_sotarks           6.1222 (3.45)     16.0620 (8.25)      6.4435 (3.48)     0.8114 (20.27)     6.3351 (3.43)     0.1677 (3.14)         3;10  155.1956 (0.29)        152           1
test_rust_galaxy_burst       6.1535 (3.46)      7.3282 (3.76)      6.4249 (3.47)     0.1903 (4.75)      6.3857 (3.46)     0.1377 (2.57)        21;10  155.6452 (0.29)        148           1
test_oppai_galaxy_burst      8.1627 (4.59)     11.3769 (5.84)      8.5283 (4.61)     0.3584 (8.96)      8.4481 (4.58)     0.2359 (4.41)          9;6  117.2565 (0.22)        110           1
test_rust_unforgiving       12.9719 (7.30)     13.9540 (7.16)     13.2572 (7.16)     0.1567 (3.92)     13.2482 (7.18)     0.1395 (2.61)         16;4   75.4307 (0.14)         71           1
test_oppai_unforgiving      22.4598 (12.64)    35.3505 (18.15)    23.6072 (12.76)    2.4802 (61.97)    22.8837 (12.41)    0.4452 (8.32)          3;4   42.3600 (0.08)         44           1
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Simple Benchmarks

Native vs wrapped beatmap object

Read and parsing time spent on beatmap of different sizes (forgiving is a beatmap over 50 minutes long and takes the longest)

There are also subtle differences in the different calling methods


MIT

pure-peace

You might also like...
Script to calculate delegator epoch returns for all pillars

znn_delegator_calculator Script to calculate estimated delegator epoch returns for all Pillars, so you can delegate to the best one. You can find me o

A weekly dive into commonly used modules in the Rust ecosystem, with story flavor!

The goal of this project is to bring the same concept as PyMOTW to the Rust world. PyMOTW was an invaluable resource for me when I was learning Python years ago, and I hope that I can help someone in a similar way. Each week we'll dive into a module and explore some of the functionality that we can find there while following along the adventures of some colourful characters.

A tool to assist in code raiding in rust
A tool to assist in code raiding in rust

Kodelock a tool to assist in code raiding in rust This tool is designed to be used on a second monitor. This tools will allow you to see a easily read

PyWorkflow(PyWF) - A Python Binding of C++ Workflow

PyWorkflow(PyWF) - A Python Binding of C++ Workflow 概览 C++ Workflow是一个高性能的异步引擎,本项目着力于实现一个Python版的Workflow,让Python用户也能享受Workflow带来的绝佳体验。

jmespath.rs Python binding

rjmespath-py jmespath.rs Python binding.

Tindicators is a Python library to calculate the values of various technical indicators

Tindicators is a Python library to calculate the values of various technical indicators

Flames Calculater App used to calculate flames status between two names created using python's Flask web framework.
Flames Calculater App used to calculate flames status between two names created using python's Flask web framework.

Flames Finder Web App Flames Calculater App used to calculate flames status between two names created using python's Flask web framework. First, App g

A program to calculate the are of a triangle. made with Python.
A program to calculate the are of a triangle. made with Python.

Area-Calculator What is Area-Calculator? Area-Calculator is a program to find out the area of a triangle easily. fully made with Python. Needed a pyth

Comments
  • configuration error: `project.license` must be valid exactly by one definition (2 matches found):

    configuration error: `project.license` must be valid exactly by one definition (2 matches found):

    Hi ! By installing the package to install bancho.py, I've encountered a problem with the pkg.

    Collecting peace-performance-python==1.1.2
      Downloading peace-performance-python-1.1.2.tar.gz (25 kB)
      Installing build dependencies ... done
      Getting requirements to build wheel ... error
      error: subprocess-exited-with-error
      
      × Getting requirements to build wheel did not run successfully.
      │ exit code: 1
      ╰─> [80 lines of output]
          configuration error: `project.license` must be valid exactly by one definition (2 matches found):
          
              - keys:
                  'file': {type: string}
                required: ['file']
              - keys:
                  'text': {type: string}
                required: ['text']
          
          DESCRIPTION:
              `Project license <https://www.python.org/dev/peps/pep-0621/#license>`_.
          
          GIVEN VALUE:
              "MIT"
          
          OFFENDING RULE: 'oneOf'
          
          DEFINITION:
              {
                  "oneOf": [
                      {
                          "properties": {
                              "file": {
                                  "type": "string",
                                  "$$description": [
                                      "Relative path to the file (UTF-8) which contains the license for the",
                                      "project."
                                  ]
                              }
                          },
                          "required": [
                              "file"
                          ]
                      },
                      {
                          "properties": {
                              "text": {
                                  "type": "string",
                                  "$$description": [
                                      "The license of the project whose meaning is that of the",
                                      "`License field from the core metadata",
                                      "<https://packaging.python.org/specifications/core-metadata/#license>`_."
                                  ]
                              }
                          },
                          "required": [
                              "text"
                          ]
                      }
                  ]
              }
          Traceback (most recent call last):
            File "/usr/local/lib/python3.9/dist-packages/pip/_vendor/pep517/in_process/_in_process.py", line 363, in <module>
              main()
            File "/usr/local/lib/python3.9/dist-packages/pip/_vendor/pep517/in_process/_in_process.py", line 345, in main
              json_out['return_val'] = hook(**hook_input['kwargs'])
            File "/usr/local/lib/python3.9/dist-packages/pip/_vendor/pep517/in_process/_in_process.py", line 130, in get_requires_for_build_wheel
              return hook(config_settings)
            File "/usr/local/lib/python3.9/dist-packages/setuptools/build_meta.py", line 177, in get_requires_for_build_wheel
              return self._get_build_requires(
            File "/usr/local/lib/python3.9/dist-packages/setuptools/build_meta.py", line 159, in _get_build_requires
              self.run_setup()
            File "/usr/local/lib/python3.9/dist-packages/setuptools/build_meta.py", line 281, in run_setup
              super(_BuildMetaLegacyBackend,
            File "/usr/local/lib/python3.9/dist-packages/setuptools/build_meta.py", line 174, in run_setup
              exec(code, locals())
            File "<string>", line 20, in <module>
            File "/usr/local/lib/python3.9/dist-packages/setuptools/__init__.py", line 87, in setup
              return distutils.core.setup(**attrs)
            File "/usr/local/lib/python3.9/dist-packages/setuptools/_distutils/core.py", line 151, in setup
              dist.parse_config_files()
            File "/usr/local/lib/python3.9/dist-packages/setuptools/dist.py", line 868, in parse_config_files
              pyprojecttoml.apply_configuration(self, filename, ignore_option_errors)
            File "/usr/local/lib/python3.9/dist-packages/setuptools/config/pyprojecttoml.py", line 58, in apply_configuration
              config = read_configuration(filepath, True, ignore_option_errors, dist)
            File "/usr/local/lib/python3.9/dist-packages/setuptools/config/pyprojecttoml.py", line 122, in read_configuration
              validate(subset, filepath)
            File "/usr/local/lib/python3.9/dist-packages/setuptools/config/pyprojecttoml.py", line 47, in validate
              raise error from None
          ValueError: invalid pyproject.toml config: `project.license`
          [end of output]
      
      note: This error originates from a subprocess, and is likely not a problem with pip.
    error: subprocess-exited-with-error
    
    × Getting requirements to build wheel did not run successfully.
    │ exit code: 1
    ╰─> See above for output.
    
    note: This error originates from a subprocess, and is likely not a problem with pip.
    

    Got this error on a clean install (Ubuntu 22) & by following the steps of bancho.py installation. I didn't have this problem on x86 but since I moved to an aarch64 (ARM), it happened.

    opened by Lxmune 1
Releases(release-v2.0.0)
Owner
纯和平
清晰易读的7x7像素点阵中文字体和取模工具

FontChinese7x7 上古神器 III : 7x7像素点阵中文字体 想要在低分辨率屏幕上显示中文, 却发现中文字体实在是太大? 找了全网发现字体库最小也只有12x12? 甚至是好不容易找到了一个8x8字体, 结果发现字体收费且明确说明不得以任何形式嵌入到软件当中? 那就让这个项目来解决你的问

Angelic47 72 Dec 12, 2022
Spinning waffle from waffle shaped python code

waffle Spinning waffle from waffle shaped python code Based on a parametric curve: r(t) = 2 - 2*sin(t) + (sin(t)*abs(cos(t)))/(sin(t) + 1.4) projected

Viljar Femoen 5 Feb 14, 2022
A tool to nowcast quarterly data with monthly indicators: US consumption example

MIDAS_Nowcaster A tool to nowcast quarterly data with monthly indicators: US consumption example Pulls data directly from FRED from a list of codes -

Gene Kindberg-Hanlon 3 Oct 06, 2022
B-Pkg is a simple tool in python for installing all basic package in termux

Basic-Pkg 👉🏻 Basic-Pkg 👈🏻 B-Pkg is a simple tool in python for installing all basic package in termux This is my first tool, I hope you will like

Macgaiver 3 Oct 21, 2021
Doom o’clock is a website/project that features a countdown of “when will the earth end” and a greenhouse gas effect emission prediction that’s predicted

Doom o’clock is a website/project that features a countdown of “when will the earth end” and a greenhouse gas effect emission prediction that’s predicted

shironeko(Hazel) 4 Jan 01, 2022
Protocol Buffers for the Rest of Us

Protocol Buffers for the Rest of Us Motivation protoletariat has one goal: fixing the broken imports for the Python code generated by protoc. Usage He

Phillip Cloud 76 Jan 04, 2023
Unofficial package for fetching users information based on National ID Number (Tanzania)

Nida Unofficial package for fetching users information based on National ID Number made by kalebu Installation You can install it directly or using pi

Jordan Kalebu 57 Dec 28, 2022
Learning objective: Use React.js, Axios, and CSS to build a responsive YouTube clone app

Learning objective: Use React.js, Axios, and CSS to build a responsive YouTube clone app to search for YouTube videos, channels, playlists, and live events via wrapper around Google YouTube API.

Dillon 0 May 03, 2022
An esoteric programming language that supports concurrency, regex, and web requests.

The Hofstadter Esoteric Programming Language Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's La

Austin Henley 19 Dec 27, 2022
People tracker on the Internet: OSINT analysis and research tool by Jose Pino

trape (stable) v2.0 People tracker on the Internet: Learn to track the world, to avoid being traced. Trape is an OSINT analysis and research tool, whi

Jose Pino 7.3k Dec 30, 2022
A set of tools for ripping music from Konami mobile games

Konami Mobile Ripping Toolset A set of tools for ripping music from Konami mobile games Contents nigger.py for niggering konami's website, ripping all

5 Oct 20, 2022
Scientific Programming: A Crash Course

Scientific Programming: A Crash Course Welcome to the Scientific Programming course. My name is Jon Carr and I am a postdoc in Davide Crepaldi's lab.

Jon Carr 1 Feb 17, 2022
Choice Coin 633 Dec 23, 2022
ARA Records Ansible and makes it easier to understand and troubleshoot.

ARA Records Ansible ARA Records Ansible and makes it easier to understand and troubleshoot. It's another recursive acronym. What it does Simple to ins

Community managed Ansible repositories 1.6k Dec 25, 2022
Python binding to rust zw-fast-quantile

zw_fast_quantile_py zw-fast-quantile python binding Installation pip install zw_fast_quantile_py Usage import zw_fast_quantile_py

Paul Meng 1 Dec 30, 2021
Hspice-Wave-Generator is a tool used to quickly generate stimuli souces of hspice format

Hspice-Wave-Generator is a tool used to quickly generate stimuli souces of hspice format. All the stimuli sources are based on `pwl` function of HSPICE and the specific complex operations of writing

3 Aug 02, 2022
:art: Diagram as Code for prototyping cloud system architectures

Diagrams Diagram as Code. Diagrams lets you draw the cloud system architecture in Python code. It was born for prototyping a new system architecture d

MinJae Kwon 27.5k Jan 04, 2023
This is a far more in-depth and advanced version of "Write user interface to a file API Sample"

Fusion360-Write-UserInterface This is a far more in-depth and advanced version of "Write user interface to a file API Sample" from https://help.autode

4 Mar 18, 2022
Simple python script for AD enumeration

AutoAD - Simple python script for AD enumeration This tool was created on my spare time to help fellow penetration testers in automating the basic enu

Mohammad Arman 28 Jun 21, 2022
It really seems like Trump is trying to get his own social media started. Not a huge fan tbh.

FuckTruthSocial It really seems like Trump is trying to get his own social media started. Not a huge fan tbh. (When TruthSocial actually releases, I'l

0 Jul 18, 2022