From be24c1a639c36e876c269ceca9568cda308c3359 Mon Sep 17 00:00:00 2001 From: Andrei Stoica Date: Sun, 28 Jan 2024 20:38:37 -0500 Subject: [PATCH] refactored out transofmations to own file --- src/extract.py | 176 ----- src/transform.py | 188 ++++++ test/test_transform.py | 1380 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1568 insertions(+), 176 deletions(-) create mode 100644 src/transform.py create mode 100644 test/test_transform.py diff --git a/src/extract.py b/src/extract.py index 056f121..f265370 100644 --- a/src/extract.py +++ b/src/extract.py @@ -1,9 +1,5 @@ import psycopg2 as pg from os import environ as env -from typing import TypeVar - -T = TypeVar("T") -U = TypeVar("U") def connect(): @@ -14,175 +10,3 @@ def connect(): host=env.get("POSTGRES_HOST"), port=env.get("POSTGRES_PORT"), ) - - -def extract_cols(data: dict, cols: list[str]) -> dict: return {key: data.get(key) for key in cols} - - -def score_to_text(score: list[int]) -> str: - return "-".join(map(str, score)) - - -# maybe could get columns form db -def cols_from_player_stats(player_stats: dict) -> dict: - cols = [ - "id", - "gameId", - "gameFinishedAt", - "steam64Id", - "name", - "preaim", - "reactionTime", - "accuracy", - "accuracyEnemySpotted", - "accuracyHead", - "shotsFiredEnemySpotted", - "shotsFired", - "shotsHitEnemySpotted", - "shotsHitFriend", - "shotsHitFriendHead", - "shotsHitFoe", - "shotsHitFoeHead", - "utilityOnDeathAvg", - "heFoesDamageAvg", - "heFriendsDamageAvg", - "heThrown", - "molotovThrown", - "smokeThrown", - "smokeThrownCT", - "smokeThrownCTGood", - "smokeThrownCTGoodRatio", - "smokeThrownCTFoes", - "counterStrafingShotsAll", - "counterStrafingShotsBad", - "counterStrafingShotsGood", - "counterStrafingShotsGoodRatio", - "flashbangHitFoe", - "flashbangLeadingToKill", - "flashbangHitFoeAvgDuration", - "flashbangHitFriend", - "flashbangThrown", - "flashAssist", - "score", - "initialTeamNumber", - "mvps", - "ctRoundsWon", - "ctRoundsLost", - "tRoundsWon", - "tRoundsLost", - "sprayAccuracy", - "molotovFoesDamageAvg", - "molotovFriendsDamageAvg", - "color", - "totalKills", - "totalDeaths", - "kdRatio", - "multi2k", - "multi3k", - "multi4k", - "multi5k", - "hltvRating", - "hsp", - "roundsSurvived", - "roundsSurvivedPercentage", - "dpr", - "totalAssists", - "totalDamage", - "tradeKillOpportunities", - "tradeKillAttempts", - "tradeKillsSucceeded", - "tradeKillAttemptsPercentage", - "tradeKillsSuccessPercentage", - "tradeKillOpportunitiesPerRound", - "tradedDeathOpportunities", - "tradedDeathAttempts", - "tradedDeathAttemptsPercentage", - "tradedDeathsSucceeded", - "tradedDeathsSuccessPercentage", - "tradedDeathsOpportunitiesPerRound", - "leetifyRating", - "personalPerformanceRating", - "ctLeetifyRating", - "tLeetifyRating", - "leetifyUserId", - "isCollector", - "isProPlan", - "isLeetifyStaff", - ] - - return extract_cols(player_stats, cols) - - -def cols_from_profile_game(game: dict) -> dict: - cols = [ - "ctLeetifyRating", - "ctLeetifyRatingRounds", - "dataSource", - "elo", - "gameFinishedAt", - "gameId", - "isCs2", - "mapName", - "matchResult", - "scores", - "skillLevel", - "tLeetifyRating", - "tLeetifyRatingRounds", - "deaths", - "hasBannedPlayer", - "kills", - "partySize", - ] - return extract_cols(game, cols) - - -def meta_from_profile(profile: dict) -> dict: - meta = profile.get("meta") - if not meta: - raise Exception("Could not get profile metadata", profile) - - cols = [ - "name", - "steam64Id", - "isCollector", - "isLeetifyStaff", - "isProPlan", - "leetifyUserId", - "faceitNickname", - ] - - return extract_cols(meta, cols) - - -def insert_value(data: dict[T, U], key: T, value: U) -> dict[T, U]: - data[key] = value - return data - - -def convert_game_scores(game: dict) -> dict: - score = game.get("scores") - if not score: - raise Exception("Could not get score from prfile game", game) - - score = score_to_text(score) - game["scores"] = score - return game - - -def games_from_profile(profile: dict) -> list: - games = profile.get("games") - if not games and not type(games) == list: - raise Exception("Could not get games from profile", profile) - - meta = profile.get("meta") - if not meta: - raise Exception("Could not get profile metadata", profile) - - id = meta.get("leetifyUserId") - if not id: - raise Exception("Could not get id from profile metadata", meta, profile) - - games = map(cols_from_profile_game, games) - games = map(lambda game: insert_value(game, "leetifyUserId", id), games) - games = map(convert_game_scores, games) - return list(games) diff --git a/src/transform.py b/src/transform.py new file mode 100644 index 0000000..d8d3a66 --- /dev/null +++ b/src/transform.py @@ -0,0 +1,188 @@ +from typing import TypeVar + +T = TypeVar("T") +U = TypeVar("U") + + +def extract_cols(data: dict, cols: list[str]) -> dict: + return {key: data.get(key) for key in cols} + + +def score_to_text(score: list[int]) -> str: + return "-".join(map(str, score)) + + +# maybe could get columns form db +def cols_from_player_stats(player_stats: dict) -> dict: + cols = [ + "id", + "gameId", + "gameFinishedAt", + "steam64Id", + "name", + "preaim", + "reactionTime", + "accuracy", + "accuracyEnemySpotted", + "accuracyHead", + "shotsFiredEnemySpotted", + "shotsFired", + "shotsHitEnemySpotted", + "shotsHitFriend", + "shotsHitFriendHead", + "shotsHitFoe", + "shotsHitFoeHead", + "utilityOnDeathAvg", + "heFoesDamageAvg", + "heFriendsDamageAvg", + "heThrown", + "molotovThrown", + "smokeThrown", + "smokeThrownCT", + "smokeThrownCTGood", + "smokeThrownCTGoodRatio", + "smokeThrownCTFoes", + "counterStrafingShotsAll", + "counterStrafingShotsBad", + "counterStrafingShotsGood", + "counterStrafingShotsGoodRatio", + "flashbangHitFoe", + "flashbangLeadingToKill", + "flashbangHitFoeAvgDuration", + "flashbangHitFriend", + "flashbangThrown", + "flashAssist", + "score", + "initialTeamNumber", + "mvps", + "ctRoundsWon", + "ctRoundsLost", + "tRoundsWon", + "tRoundsLost", + "sprayAccuracy", + "molotovFoesDamageAvg", + "molotovFriendsDamageAvg", + "color", + "totalKills", + "totalDeaths", + "kdRatio", + "multi2k", + "multi3k", + "multi4k", + "multi5k", + "hltvRating", + "hsp", + "roundsSurvived", + "roundsSurvivedPercentage", + "dpr", + "totalAssists", + "totalDamage", + "tradeKillOpportunities", + "tradeKillAttempts", + "tradeKillsSucceeded", + "tradeKillAttemptsPercentage", + "tradeKillsSuccessPercentage", + "tradeKillOpportunitiesPerRound", + "tradedDeathOpportunities", + "tradedDeathAttempts", + "tradedDeathAttemptsPercentage", + "tradedDeathsSucceeded", + "tradedDeathsSuccessPercentage", + "tradedDeathsOpportunitiesPerRound", + "leetifyRating", + "personalPerformanceRating", + "ctLeetifyRating", + "tLeetifyRating", + "leetifyUserId", + "isCollector", + "isProPlan", + "isLeetifyStaff", + ] + + return extract_cols(player_stats, cols) + + +def cols_from_profile_game(game: dict) -> dict: + cols = [ + "ctLeetifyRating", + "ctLeetifyRatingRounds", + "dataSource", + "elo", + "gameFinishedAt", + "gameId", + "isCs2", + "mapName", + "matchResult", + "scores", + "skillLevel", + "tLeetifyRating", + "tLeetifyRatingRounds", + "deaths", + "hasBannedPlayer", + "kills", + "partySize", + ] + return extract_cols(game, cols) + + +def meta_from_profile(profile: dict) -> dict: + meta = profile.get("meta") + if not meta: + raise Exception("Could not get profile metadata", profile) + + cols = [ + "name", + "steam64Id", + "isCollector", + "isLeetifyStaff", + "isProPlan", + "leetifyUserId", + "faceitNickname", + ] + + return extract_cols(meta, cols) + + +def insert_value(data: dict[T, U], key: T, value: U) -> dict[T, U]: + data[key] = value + return data + + +def convert_game_scores(game: dict) -> dict: + score = game.get("scores") + if not score: + raise Exception("Could not get score from prfile game", game) + + score = score_to_text(score) + game["scores"] = score + return game + + +def games_from_profile(profile: dict) -> list: + games = profile.get("games") + # emtpy list is falsy but an acceptable value + if not games and not type(games) == list: + raise Exception("Could not get games from profile", profile) + + meta = profile.get("meta") + if not meta: + raise Exception("Could not get profile metadata", profile) + + id = meta.get("leetifyUserId") + if not id: + raise Exception("Could not get id from profile metadata", meta, profile) + + games = map(cols_from_profile_game, games) + games = map(lambda game: insert_value(game, "leetifyUserId", id), games) + games = map(convert_game_scores, games) + return list(games) + + +def player_stats_from_game(game: dict) -> list[dict]: + stats = game.get("playerStats") + if not stats: + raise Exception("Could not get stats from game", game) + + + stats = map(cols_from_player_stats,stats) + return list(stats) diff --git a/test/test_transform.py b/test/test_transform.py new file mode 100644 index 0000000..f88c418 --- /dev/null +++ b/test/test_transform.py @@ -0,0 +1,1380 @@ +from src import transform as tr +from pytest import fixture + +@fixture +def profile(): + return { + "highlights": [ + { + "createdAt": "2023-12-10T22:36:26.813Z", + "description": "AK-47 4K on Overpass", + "gameId": "4647ec10-dc9a-4afd-b9e0-144a462970b2", + "id": "7f4fc8a6-6198-47e1-aa96-f455b70b1f04", + "isPinned": True, + "pendingPro": False, + "rankValue": None, + "roundNumber": 20, + "steam64Id": "76561198036388580", + "thumbnailUrl": "https://media.allstar.gg/6269b3881c45be12afd59318/thumbs/657bcaac1a8ab6000d65a27f_thumb.jpg", + "url": "https://allstar.gg/iframe?clip=657bcaac1a8ab6000d65a27f&known=false&platform=L202211&useCase=WC&sid=76561198036388580", + "username": "skaterCS", + }, + { + "createdAt": "2023-12-24T02:15:57.052Z", + "description": "AK-47 4K on Vertigo", + "gameId": "5699e90e-ec76-4ed8-99f3-7905315960ae", + "id": "6e3d2aa4-cf57-44b4-8d85-c771a4d4d5b6", + "isPinned": True, + "pendingPro": False, + "rankValue": None, + "roundNumber": 18, + "steam64Id": "76561198036388580", + "thumbnailUrl": "https://media.allstar.gg/6269b3881c45be12afd59318/thumbs/658e3f6d0c66ff000d4e93a3_thumb.jpg", + "url": "https://allstar.gg/iframe?clip=658e3f6d0c66ff000d4e93a3&known=false&platform=L202211&useCase=WC&sid=76561198036388580", + "username": "skaterCS", + }, + { + "createdAt": "2023-12-31T23:53:11.150Z", + "description": "4K on Anubis", + "gameId": "2466135e-aae5-4966-a11f-477cceee6499", + "id": "51aac0ff-5140-46ad-8e46-db6d752f99b1", + "isPinned": False, + "pendingPro": False, + "rankValue": None, + "roundNumber": 6, + "steam64Id": "76561198036388580", + "thumbnailUrl": "https://media.allstar.gg/6269b3881c45be12afd59318/thumbs/6597a2d4589d590012898af7_thumb.jpg", + "url": "https://allstar.gg/iframe?clip=6597a2d4589d590012898af7&known=false&platform=L202211&useCase=WC&sid=76561198036388580", + "username": "skaterCS", + }, + { + "createdAt": "2024-01-08T00:48:19.753Z", + "description": "AK-47 4K on Inferno", + "gameId": "6691ea4b-4d5d-4ffc-aabd-ac6f2ce291c0", + "id": "e85ca957-e6cb-4d96-9f02-1850af23d5b0", + "isPinned": False, + "pendingPro": False, + "rankValue": None, + "roundNumber": 22, + "steam64Id": "76561198036388580", + "thumbnailUrl": "https://media.allstar.gg/6269b3881c45be12afd59318/thumbs/65a108eba0d42f000c9af008_thumb.jpg", + "url": "https://allstar.gg/iframe?clip=65a108eba0d42f000c9af008&known=false&platform=L202211&useCase=WC&sid=76561198036388580", + "username": "skaterCS", + }, + { + "createdAt": "2024-01-13T20:50:07.002Z", + "description": "AK-47 4K on Ancient", + "gameId": "a3f0c4b6-da37-43c4-8679-b6b858ec1600", + "id": "90af8cd2-3224-4bc6-9dc9-d778ed93339c", + "isPinned": False, + "pendingPro": False, + "rankValue": None, + "roundNumber": 10, + "steam64Id": "76561198036388580", + "thumbnailUrl": "https://media.allstar.gg/6269b3881c45be12afd59318/thumbs/65ac1f0b230e6e000dba9cbc_thumb.jpg", + "url": "https://allstar.gg/iframe?clip=65ac1f0b230e6e000dba9cbc&known=false&platform=L202211&useCase=WC&sid=76561198036388580", + "username": "skaterCS", + }, + ], + "personalBests": [], + "recentGameRatings": { + "aim": 67.72418696226975, + "positioning": 36.31694139929697, + "utility": 51.595349880463615, + "gamesPlayed": 30, + "leetifyRatingRounds": 620, + "clutch": 0.13, + "ctLeetify": -0.0114, + "leetify": -0.0121, + "opening": -0.0598, + "tLeetify": -0.0128, + }, + "teammates": [ + { + "isCollector": False, + "isProPlan": False, + "leetifyUserId": "5e28e0c9-4b01-4fa3-b568-c9ae56ed8ac1", + "isBanned": False, + "isLeetifyStaff": False, + "matchesPlayedTogether": 32, + "profileUserLeetifyRating": -0.0016909883720930246, + "rank": { + "type": "premier", + "dataSource": "matchmaking", + "skillLevel": 15267, + }, + "steam64Id": "76561198228115488", + "steamAvatarUrl": "https://avatars.steamstatic.com/361d26bb315644059663ab9c32479c09bddbcb96_full.jpg", + "steamNickname": "AustinShyd", + "teammateLeetifyRating": 0.013207703488372092, + "winRateTogether": 0.5666666666666667, + }, + { + "isCollector": False, + "isProPlan": True, + "leetifyUserId": "8c3a9cb5-faaf-4401-ae9a-72f5e8528651", + "isBanned": False, + "isLeetifyStaff": False, + "matchesPlayedTogether": 21, + "profileUserLeetifyRating": -0.0037864444444444456, + "rank": {"dataSource": "faceit", "skillLevel": 6}, + "steam64Id": "76561198376400117", + "steamAvatarUrl": "https://avatars.akamai.steamstatic.com/8e0029277f9fe4f57d9319d6143cbf72df0d717f_full.jpg", + "steamNickname": "TiMe_TrAvLeR87", + "teammateLeetifyRating": -0.002907555555555556, + "winRateTogether": 0.5714285714285714, + }, + { + "isCollector": False, + "isProPlan": False, + "leetifyUserId": "163b492d-931d-4021-bdb9-6e6d4f37b2b2", + "isBanned": False, + "isLeetifyStaff": False, + "matchesPlayedTogether": 11, + "profileUserLeetifyRating": 0.01336536964980545, + "rank": { + "type": "premier", + "dataSource": "matchmaking", + "skillLevel": 9135, + }, + "steam64Id": "76561198019127603", + "steamAvatarUrl": "https://avatars.steamstatic.com/b93f04b9194fba8980a2dc74947d47d0087ba113_full.jpg", + "steamNickname": "Lit Taco", + "teammateLeetifyRating": -0.02468832684824903, + "winRateTogether": 0.6363636363636364, + }, + { + "isCollector": False, + "isProPlan": False, + "leetifyUserId": "a47ba360-5fb1-4b88-b701-31f7c7ae4659", + "isBanned": False, + "isLeetifyStaff": False, + "matchesPlayedTogether": 27, + "profileUserLeetifyRating": 0.014388762214983713, + "rank": {"dataSource": "faceit", "skillLevel": 2}, + "steam64Id": "76561197992874735", + "steamAvatarUrl": "https://avatars.steamstatic.com/1982d13a52fa8e8364d681966972a1de70a36c64_full.jpg", + "steamNickname": "Mela", + "teammateLeetifyRating": -0.02852671009771987, + "winRateTogether": 0.5185185185185185, + }, + { + "isCollector": False, + "isProPlan": False, + "leetifyUserId": "f6b4342b-3779-4144-9e53-9d4d408a315c", + "isBanned": False, + "isLeetifyStaff": False, + "matchesPlayedTogether": 22, + "profileUserLeetifyRating": 0.013741448692152916, + "rank": {"dataSource": "faceit", "skillLevel": 6}, + "steam64Id": "76561199022813257", + "steamAvatarUrl": "https://avatars.steamstatic.com/1ce49c3e9b812ab90ef16d34bfaf60193e7a7489_full.jpg", + "steamNickname": "Sharky", + "teammateLeetifyRating": 0.02733762575452716, + "winRateTogether": 0.5, + }, + { + "isCollector": False, + "isProPlan": False, + "leetifyUserId": "95921f4b-e2aa-466a-adce-4b53b220cc2d", + "isBanned": False, + "isLeetifyStaff": False, + "matchesPlayedTogether": 13, + "profileUserLeetifyRating": -0.0076067375886524815, + "rank": { + "type": "premier", + "dataSource": "matchmaking", + "skillLevel": 14568, + }, + "steam64Id": "76561199046277694", + "steamAvatarUrl": "https://avatars.akamai.steamstatic.com/ccd7f5b712406dbbfccc544005fd4731a777c5a1_full.jpg", + "steamNickname": "fwdz", + "teammateLeetifyRating": 0.03853794326241135, + "winRateTogether": 0.5, + }, + { + "isCollector": False, + "isProPlan": False, + "leetifyUserId": "a3619755-fffa-49a3-8074-03e1de9dc2c1", + "isBanned": True, + "isLeetifyStaff": False, + "matchesPlayedTogether": 43, + "profileUserLeetifyRating": -0.00885761802575107, + "rank": { + "type": "premier", + "dataSource": "matchmaking", + "skillLevel": 10001, + }, + "steam64Id": "76561198051811238", + "steamAvatarUrl": "https://avatars.akamai.steamstatic.com/4611b64e6ea807573525239f57e55fc2ccdbedd7_full.jpg", + "steamNickname": "Revolver_FPS", + "teammateLeetifyRating": -0.02219978401727862, + "winRateTogether": 0.5, + }, + { + "isCollector": False, + "isProPlan": False, + "leetifyUserId": "70faf9da-07f9-4a24-afe9-fb84be5d7706", + "isBanned": False, + "isLeetifyStaff": False, + "matchesPlayedTogether": 33, + "profileUserLeetifyRating": 0.00413012729844413, + "rank": { + "type": "premier", + "dataSource": "matchmaking", + "skillLevel": 10243, + }, + "steam64Id": "76561198174606711", + "steamAvatarUrl": "https://avatars.akamai.steamstatic.com/e903300342a9eba51d920af5b2ea10080f270a42_full.jpg", + "steamNickname": "Mqple", + "teammateLeetifyRating": 0.008475536480686696, + "winRateTogether": 0.48484848484848486, + }, + { + "isCollector": False, + "isProPlan": False, + "isBanned": False, + "isLeetifyStaff": False, + "matchesPlayedTogether": 11, + "profileUserLeetifyRating": -0.01507543859649123, + "rank": {"dataSource": "faceit", "skillLevel": 5}, + "steam64Id": "76561198216410960", + "steamAvatarUrl": "https://avatars.akamai.steamstatic.com/2e601d5cd472b63f3b5235364d55e2f6b99ec326_full.jpg", + "steamNickname": "Yaw", + "teammateLeetifyRating": 0.02286578947368421, + "winRateTogether": 0.5454545454545454, + }, + ], + "games": [ + { + "enemyTeamSteam64Ids": [ + "76561198017884049", + "76561198376400117", + "76561198097337225", + "76561198801253208", + "76561198883031817", + ], + "isCompletedLongMatch": False, + "ownTeamSteam64Ids": [ + "76561198060167512", + "76561198036388580", + "76561198048048148", + "76561198246440596", + "76561198108997204", + ], + "ownTeamTotalLeetifyRatingRounds": { + "76561198060167512": 23, + "76561198036388580": 23, + "76561198048048148": 23, + "76561198246440596": 23, + "76561198108997204": 23, + }, + "ownTeamTotalLeetifyRatings": { + "76561198060167512": 0.0473, + "76561198036388580": 0.0773, + "76561198048048148": -0.0426, + "76561198246440596": -0.0048, + "76561198108997204": -0.0049, + }, + "ctLeetifyRating": -0.0157, + "ctLeetifyRatingRounds": 12, + "dataSource": "faceit", + "elo": 1273, + "gameFinishedAt": "2024-01-13T20:45:53.000Z", + "gameId": "a3f0c4b6-da37-43c4-8679-b6b858ec1600", + "isCs2": True, + "mapName": "de_ancient", + "matchResult": "win", + "rankType": None, + "scores": [13, 10], + "skillLevel": 6, + "tLeetifyRating": 0.1625, + "tLeetifyRatingRounds": 11, + "deaths": 11, + "hasBannedPlayer": False, + "kills": 19, + "partySize": 1, + }, + { + "enemyTeamSteam64Ids": [ + "76561198052273476", + "76561199145898951", + "76561199239125525", + "76561198086636793", + "76561199009125853", + ], + "isCompletedLongMatch": False, + "ownTeamSteam64Ids": [ + "76561198036388580", + "76561198123663481", + "76561198212556913", + "76561198282254268", + "76561198218979692", + ], + "ownTeamTotalLeetifyRatingRounds": { + "76561198036388580": 18, + "76561198123663481": 18, + "76561198212556913": 18, + "76561198282254268": 18, + "76561198218979692": 18, + }, + "ownTeamTotalLeetifyRatings": { + "76561198036388580": 0.0138, + "76561198123663481": 0.0004, + "76561198212556913": -0.0143, + "76561198282254268": 0.0516, + "76561198218979692": 0.1367, + }, + "ctLeetifyRating": -0.015, + "ctLeetifyRatingRounds": 6, + "dataSource": "faceit", + "elo": 1248, + "gameFinishedAt": "2024-01-13T00:51:26.000Z", + "gameId": "ba78c2f5-99b8-4d4d-afbd-cacee7894dbb", + "isCs2": True, + "mapName": "de_vertigo", + "matchResult": "win", + "rankType": None, + "scores": [13, 5], + "skillLevel": 6, + "tLeetifyRating": 0.0715, + "tLeetifyRatingRounds": 12, + "deaths": 12, + "hasBannedPlayer": False, + "kills": 13, + "partySize": 1, + }, + { + "enemyTeamSteam64Ids": [ + "76561198180054591", + "76561198103217250", + "76561198255756012", + "76561199228602800", + "76561198131413139", + ], + "isCompletedLongMatch": False, + "ownTeamSteam64Ids": [ + "76561198799389823", + "76561198068730110", + "76561198086636793", + "76561199145898951", + "76561198036388580", + ], + "ownTeamTotalLeetifyRatingRounds": { + "76561198799389823": 24, + "76561198068730110": 24, + "76561198086636793": 24, + "76561199145898951": 24, + "76561198036388580": 24, + }, + "ownTeamTotalLeetifyRatings": { + "76561198799389823": -0.0014, + "76561198068730110": 0.0375, + "76561198086636793": -0.0134, + "76561199145898951": -0.0543, + "76561198036388580": -0.0161, + }, + "ctLeetifyRating": 0.0091, + "ctLeetifyRatingRounds": 12, + "dataSource": "faceit", + "elo": 1273, + "gameFinishedAt": "2024-01-13T00:11:36.000Z", + "gameId": "f57fc165-8d9d-4cbb-aeaf-3305bf96f6b1", + "isCs2": True, + "mapName": "de_anubis", + "matchResult": "loss", + "rankType": None, + "scores": [11, 13], + "skillLevel": 6, + "tLeetifyRating": -0.0413, + "tLeetifyRatingRounds": 12, + "deaths": 17, + "hasBannedPlayer": False, + "kills": 12, + "partySize": 1, + }, + { + "enemyTeamSteam64Ids": [ + "76561199065317871", + "76561199133043212", + "76561199237862815", + "76561197979349420", + "76561199568936482", + ], + "isCompletedLongMatch": False, + "ownTeamSteam64Ids": [ + "76561197991931943", + "76561198174606711", + "76561199057228627", + "76561198075880354", + "76561198036388580", + ], + "ownTeamTotalLeetifyRatingRounds": { + "76561197991931943": 20, + "76561198174606711": 20, + "76561199057228627": 20, + "76561198075880354": 20, + "76561198036388580": 20, + }, + "ownTeamTotalLeetifyRatings": { + "76561197991931943": -0.062, + "76561198174606711": 0.0301, + "76561199057228627": 0.0457, + "76561198075880354": 0.0723, + "76561198036388580": 0.0185, + }, + "ctLeetifyRating": 0.0273, + "ctLeetifyRatingRounds": 8, + "dataSource": "faceit", + "elo": 962, + "gameFinishedAt": "2023-11-12T19:53:56.000Z", + "gameId": "76bd9c1b-4350-4cba-a85c-853dda2319a3", + "isCs2": True, + "mapName": "de_vertigo", + "matchResult": "win", + "rankType": None, + "scores": [13, 7], + "skillLevel": 4, + "tLeetifyRating": 0.0053, + "tLeetifyRatingRounds": 12, + }, + { + "enemyTeamSteam64Ids": [ + "76561199215625191", + "76561198138569488", + "76561198882489909", + "76561198967893666", + "76561199480114036", + ], + "isCompletedLongMatch": True, + "ownTeamSteam64Ids": [ + "76561198232726872", + "76561198174606711", + "76561198036388580", + "76561198051811238", + "76561198060380124", + ], + "ownTeamTotalLeetifyRatingRounds": { + "76561198232726872": 41, + "76561198174606711": 41, + "76561198036388580": 41, + "76561198051811238": 41, + "76561198060380124": 41, + }, + "ownTeamTotalLeetifyRatings": { + "76561198232726872": 0.0271, + "76561198174606711": 0.0056, + "76561198036388580": 0.0273, + "76561198051811238": -0.0392, + "76561198060380124": -0.0188, + }, + "ctLeetifyRating": 0.0493, + "ctLeetifyRatingRounds": 21, + "dataSource": "faceit", + "elo": 910, + "gameFinishedAt": "2023-11-11T03:35:16.000Z", + "gameId": "fdd3867f-225b-4177-bc99-661a7fa43c41", + "isCs2": True, + "mapName": "de_vertigo", + "matchResult": "win", + "rankType": None, + "scores": [22, 19], + "skillLevel": 4, + "tLeetifyRating": 0.0063, + "tLeetifyRatingRounds": 20, + }, + { + "enemyTeamSteam64Ids": [ + "76561198954974027", + "76561198340039100", + "76561198267258925", + "76561198132032289", + "76561198268422115", + ], + "isCompletedLongMatch": False, + "ownTeamSteam64Ids": [ + "76561197962906363", + "76561197971574216", + "76561198036388580", + "76561198174606711", + "76561198142815385", + ], + "ownTeamTotalLeetifyRatingRounds": { + "76561197962906363": 23, + "76561197971574216": 23, + "76561198036388580": 23, + "76561198174606711": 23, + "76561198142815385": 23, + }, + "ownTeamTotalLeetifyRatings": { + "76561197962906363": -0.0855, + "76561197971574216": -0.004, + "76561198036388580": 0.0142, + "76561198174606711": 0.0311, + "76561198142815385": -0.039, + }, + "ctLeetifyRating": 0.0069, + "ctLeetifyRatingRounds": 12, + "dataSource": "faceit", + "elo": 960, + "gameFinishedAt": "2023-11-10T01:02:34.000Z", + "gameId": "73acee05-c6ce-4a15-9ab1-c4201443d6ff", + "isCs2": True, + "mapName": "de_mirage", + "matchResult": "loss", + "rankType": None, + "scores": [10, 13], + "skillLevel": 4, + "tLeetifyRating": 0.0209, + "tLeetifyRatingRounds": 11, + }, + ], + "meta": { + "name": "Skater", + "steam64Id": "76561198036388580", + "steamAvatarUrl": "https://avatars.akamai.steamstatic.com/ee0e6adb9c075b0b40cbedba2f8699d1c040ca6c_full.jpg", + "isCollector": False, + "isLeetifyStaff": False, + "isProPlan": False, + "leetifyUserId": "6c53f87a-5877-4dd3-ab8f-527119ce4939", + "faceitNickname": "skaterCS", + "platformBans": [], + }, + } + + +@fixture +def profile_games(profile): + return profile["games"] + + +@fixture +def game(): + return { + "id": "a3f0c4b6-da37-43c4-8679-b6b858ec1600", + "dataSource": "faceit", + "isCs2": True, + "faceitMatchId": None, + "hltvMatchId": None, + "replayUrl": "https://demos-us-central1.faceit-cdn.net/cs2/1-55f0bdfc-d033-42d0-900d-9f0ec419946c-1-1.dem.gz", + "mapName": "de_ancient", + "teamScores": [10, 0], + "finishedAt": "2024-01-13T20:45:53.000Z", + "status": "ready", + "retries": 3, + "nextRetryAt": None, + "errorCode": None, + "recalculate": False, + "steamShareCode": None, + "createdAt": "2024-01-13T20:45:53.966Z", + "hasBannedPlayer": False, + "hasSkeletonStats": False, + "agents": [], + "details": { + "gameId": "a3f0c4b6-da37-43c4-8679-b6b858ec1600", + "gameFinishedAt": "2024-01-13T20:45:53.000Z", + "surrenderedByInitialTeamNumber": None, + "mpMaxrounds": 24, + "gameMode": None, + "gameType": None, + "tickrate": 64, + "ticks": 135463, + "serverName": "FACEIT.com register to play here", + }, + "playerStats": [ + { + "id": "f913fc05-40ff-4f55-b8b9-b46703317455", + "gameId": "a3f0c4b6-da37-43c4-8679-b6b858ec1600", + "gameFinishedAt": "2024-01-13T20:45:53.000Z", + "steam64Id": "76561198376400117", + "name": "TiMe_TrAvLeR", + "preaim": 8.5628, + "reactionTime": 0.75, + "accuracy": 0.2333, + "accuracyEnemySpotted": 0.4298, + "accuracyHead": 0.1774, + "shotsFiredEnemySpotted": 114, + "shotsFired": 270, + "shotsHitEnemySpotted": 49, + "shotsHitFriend": 0, + "shotsHitFriendHead": 0, + "shotsHitFoe": 63, + "shotsHitFoeHead": 0, + "utilityOnDeathAvg": 605.2632, + "heFoesDamageAvg": 14.25, + "heFriendsDamageAvg": 0, + "heThrown": 4, + "molotovThrown": 7, + "smokeThrown": 2, + "smokeThrownCT": 1, + "smokeThrownCTGood": 0, + "smokeThrownCTGoodRatio": 0, + "smokeThrownCTFoes": 0, + "counterStrafingShotsAll": 78, + "counterStrafingShotsBad": 10, + "counterStrafingShotsGood": 68, + "counterStrafingShotsGoodRatio": 0.8718, + "flashbangHitFoe": 0, + "flashbangLeadingToKill": 0, + "flashbangHitFoeAvgDuration": 0, + "flashbangHitFriend": 0, + "flashbangThrown": 0, + "flashAssist": 0, + "score": 39, + "initialTeamNumber": 3, + "mvps": 5, + "ctRoundsWon": 2, + "ctRoundsLost": 10, + "tRoundsWon": 8, + "tRoundsLost": 3, + "sprayAccuracy": 0.5405, + "utilityOnDeathValues": [], + "smokeThrownCTFoesDistances": [], + "heFoesDamages": [], + "heFriendsDamages": [], + "molotovFoesDamageAvg": 1.2857, + "molotovFriendsDamageAvg": 0, + "color": 0, + "achievements": { + "0": 0, + "1": 0, + "2": 0, + "3": 0, + "personal_best_all_time": 0, + }, + "totalKills": 17, + "totalDeaths": 19, + "kdRatio": 0.89, + "multi2k": 3, + "multi3k": 2, + "multi4k": 0, + "multi5k": 0, + "hltvRating": 0.99, + "hsp": 0.5882, + "roundsSurvived": 4, + "roundsSurvivedPercentage": 0.1739, + "dpr": 84.3, + "totalAssists": 5, + "totalDamage": 1939, + "tradeKillOpportunities": 2, + "tradeKillAttempts": 1, + "tradeKillsSucceeded": 0, + "tradeKillAttemptsPercentage": 0.5, + "tradeKillsSuccessPercentage": 0, + "tradeKillOpportunitiesPerRound": 0.087, + "tradedDeathOpportunities": 4, + "tradedDeathAttempts": 2, + "tradedDeathAttemptsPercentage": 0.5, + "tradedDeathsSucceeded": 1, + "tradedDeathsSuccessPercentage": 0.5, + "tradedDeathsOpportunitiesPerRound": 0.1739, + "leetifyRating": 0.009, + "personalPerformanceRating": 0.0199, + "ctLeetifyRating": -0.021, + "tLeetifyRating": 0.0417, + "leetifyUserId": "8c3a9cb5-faaf-4401-ae9a-72f5e8528651", + "isCollector": False, + "isProPlan": True, + "isLeetifyStaff": False, + }, + { + "id": "6b39dfc3-3d7d-42d0-b69e-a56289b7bd41", + "gameId": "a3f0c4b6-da37-43c4-8679-b6b858ec1600", + "gameFinishedAt": "2024-01-13T20:45:53.000Z", + "steam64Id": "76561198801253208", + "name": "Huaran070314", + "preaim": 5.5644, + "reactionTime": 0.5156, + "accuracy": 0.1693, + "accuracyEnemySpotted": 0.47, + "accuracyHead": 0.2419, + "shotsFiredEnemySpotted": 100, + "shotsFired": 378, + "shotsHitEnemySpotted": 47, + "shotsHitFriend": 0, + "shotsHitFriendHead": 0, + "shotsHitFoe": 64, + "shotsHitFoeHead": 0, + "utilityOnDeathAvg": 166.6667, + "heFoesDamageAvg": 20.1111, + "heFriendsDamageAvg": 1.5556, + "heThrown": 9, + "molotovThrown": 6, + "smokeThrown": 7, + "smokeThrownCT": 2, + "smokeThrownCTGood": 1, + "smokeThrownCTGoodRatio": 0.5, + "smokeThrownCTFoes": 2, + "counterStrafingShotsAll": 89, + "counterStrafingShotsBad": 10, + "counterStrafingShotsGood": 79, + "counterStrafingShotsGoodRatio": 0.8876, + "flashbangHitFoe": 10, + "flashbangLeadingToKill": 0, + "flashbangHitFoeAvgDuration": 3.0426, + "flashbangHitFriend": 8, + "flashbangThrown": 16, + "flashAssist": 1, + "score": 54, + "initialTeamNumber": 3, + "mvps": 3, + "ctRoundsWon": 2, + "ctRoundsLost": 10, + "tRoundsWon": 8, + "tRoundsLost": 3, + "sprayAccuracy": 0.6389, + "utilityOnDeathValues": [], + "smokeThrownCTFoesDistances": [], + "heFoesDamages": [], + "heFriendsDamages": [], + "molotovFoesDamageAvg": 5.6667, + "molotovFriendsDamageAvg": 0, + "color": 4, + "achievements": { + "0": 0, + "1": 0, + "2": 0, + "3": 0, + "personal_best_all_time": 0, + }, + "totalKills": 22, + "totalDeaths": 15, + "kdRatio": 1.47, + "multi2k": 4, + "multi3k": 2, + "multi4k": 0, + "multi5k": 0, + "hltvRating": 1.34, + "hsp": 0.6818, + "roundsSurvived": 8, + "roundsSurvivedPercentage": 0.3478, + "dpr": 109, + "totalAssists": 4, + "totalDamage": 2507, + "tradeKillOpportunities": 7, + "tradeKillAttempts": 5, + "tradeKillsSucceeded": 3, + "tradeKillAttemptsPercentage": 0.7143, + "tradeKillsSuccessPercentage": 0.6, + "tradeKillOpportunitiesPerRound": 0.35, + "tradedDeathOpportunities": 4, + "tradedDeathAttempts": 4, + "tradedDeathAttemptsPercentage": 1, + "tradedDeathsSucceeded": 2, + "tradedDeathsSuccessPercentage": 0.5, + "tradedDeathsOpportunitiesPerRound": 0.2, + "leetifyRating": 0.068, + "personalPerformanceRating": 0.0586, + "ctLeetifyRating": -0.0229, + "tLeetifyRating": 0.1672, + }, + { + "id": "67050cd7-efe3-42ad-8d8e-4f0687dd3180", + "gameId": "a3f0c4b6-da37-43c4-8679-b6b858ec1600", + "gameFinishedAt": "2024-01-13T20:45:53.000Z", + "steam64Id": "76561198883031817", + "name": "RIPMASTERR", + "preaim": 8.3357, + "reactionTime": 0.5781, + "accuracy": 0.2, + "accuracyEnemySpotted": 0.382, + "accuracyHead": 0.1163, + "shotsFiredEnemySpotted": 89, + "shotsFired": 225, + "shotsHitEnemySpotted": 34, + "shotsHitFriend": 0, + "shotsHitFriendHead": 0, + "shotsHitFoe": 45, + "shotsHitFoeHead": 0, + "utilityOnDeathAvg": 435.2941, + "heFoesDamageAvg": 5.2, + "heFriendsDamageAvg": 0, + "heThrown": 5, + "molotovThrown": 9, + "smokeThrown": 11, + "smokeThrownCT": 7, + "smokeThrownCTGood": 2, + "smokeThrownCTGoodRatio": 0.2857, + "smokeThrownCTFoes": 2, + "counterStrafingShotsAll": 29, + "counterStrafingShotsBad": 9, + "counterStrafingShotsGood": 20, + "counterStrafingShotsGoodRatio": 0.6897, + "flashbangHitFoe": 0, + "flashbangLeadingToKill": 0, + "flashbangHitFoeAvgDuration": 0, + "flashbangHitFriend": 0, + "flashbangThrown": 0, + "flashAssist": 0, + "score": 34, + "initialTeamNumber": 3, + "mvps": 0, + "ctRoundsWon": 2, + "ctRoundsLost": 10, + "tRoundsWon": 8, + "tRoundsLost": 3, + "sprayAccuracy": 0.2, + "utilityOnDeathValues": [], + "smokeThrownCTFoesDistances": [], + "heFoesDamages": [], + "heFriendsDamages": [], + "molotovFoesDamageAvg": 0.7778, + "molotovFriendsDamageAvg": 0, + "color": 3, + "achievements": { + "0": 0, + "1": 0, + "2": 0, + "3": 0, + "personal_best_all_time": 0, + }, + "totalKills": 12, + "totalDeaths": 17, + "kdRatio": 0.71, + "multi2k": 1, + "multi3k": 0, + "multi4k": 0, + "multi5k": 0, + "hltvRating": 0.67, + "hsp": 0.3333, + "roundsSurvived": 6, + "roundsSurvivedPercentage": 0.2609, + "dpr": 52.83, + "totalAssists": 3, + "totalDamage": 1215, + "tradeKillOpportunities": 6, + "tradeKillAttempts": 4, + "tradeKillsSucceeded": 3, + "tradeKillAttemptsPercentage": 0.6667, + "tradeKillsSuccessPercentage": 0.75, + "tradeKillOpportunitiesPerRound": 0.2609, + "tradedDeathOpportunities": 7, + "tradedDeathAttempts": 7, + "tradedDeathAttemptsPercentage": 1, + "tradedDeathsSucceeded": 2, + "tradedDeathsSuccessPercentage": 0.2857, + "tradedDeathsOpportunitiesPerRound": 0.3043, + "leetifyRating": -0.0432, + "personalPerformanceRating": -0.0347, + "ctLeetifyRating": -0.0801, + "tLeetifyRating": -0.003, + "leetifyUserId": "b94bd18e-9bb3-4150-aa5a-596adfe29103", + "isCollector": False, + "isProPlan": False, + "isLeetifyStaff": False, + }, + ], + "playerMatchResults": [], + "openingDuelPlayerStats": [], + "matchmakingGameStats": [], + "faceitGameStats": [], + "gamersClubGameStats": [], + "gamePlayerRoundSkeletonStats": [], + "replayFile": { + "id": "007d202f-8b72-4162-9f82-213c62dffef3", + "gameId": "a3f0c4b6-da37-43c4-8679-b6b858ec1600", + "createdAt": "2024-01-13T20:49:39.100Z", + "updatedAt": "2024-01-13T20:49:39.100Z", + }, + "parties": [], + } + + +def test_extract_cols(profile): + empty_dict = {} + cols = ["meta"] + + res = tr.extract_cols(empty_dict, []) + assert res == {} + + res = tr.extract_cols(empty_dict, cols) + assert res == {"meta": None} + + res = tr.extract_cols(profile, []) + assert res == {} + + res = tr.extract_cols(profile, cols) + assert res == { + "meta": { + "name": "Skater", + "steam64Id": "76561198036388580", + "steamAvatarUrl": "https://avatars.akamai.steamstatic.com/ee0e6adb9c075b0b40cbedba2f8699d1c040ca6c_full.jpg", + "isCollector": False, + "isLeetifyStaff": False, + "isProPlan": False, + "leetifyUserId": "6c53f87a-5877-4dd3-ab8f-527119ce4939", + "faceitNickname": "skaterCS", + "platformBans": [], + }, + } + + cols.append("recentGameRatings") + res = tr.extract_cols(profile, cols) + assert res == { + "meta": { + "name": "Skater", + "steam64Id": "76561198036388580", + "steamAvatarUrl": "https://avatars.akamai.steamstatic.com/ee0e6adb9c075b0b40cbedba2f8699d1c040ca6c_full.jpg", + "isCollector": False, + "isLeetifyStaff": False, + "isProPlan": False, + "leetifyUserId": "6c53f87a-5877-4dd3-ab8f-527119ce4939", + "faceitNickname": "skaterCS", + "platformBans": [], + }, + "recentGameRatings": { + "aim": 67.72418696226975, + "positioning": 36.31694139929697, + "utility": 51.595349880463615, + "gamesPlayed": 30, + "leetifyRatingRounds": 620, + "clutch": 0.13, + "ctLeetify": -0.0114, + "leetify": -0.0121, + "opening": -0.0598, + "tLeetify": -0.0128, + }, + } + + +def test_score_to_text(): + text = tr.score_to_text([]) + assert text == "" + + text = tr.score_to_text([1]) + assert text == "1" + + text = tr.score_to_text([1, 2]) + assert text == "1-2" + + text = tr.score_to_text([1, 2, 3]) + assert text == "1-2-3" + + +def test_meta_from_profile(profile): + res = tr.meta_from_profile(profile) + assert res == { + "name": "Skater", + "steam64Id": "76561198036388580", + "isCollector": False, + "isLeetifyStaff": False, + "isProPlan": False, + "leetifyUserId": "6c53f87a-5877-4dd3-ab8f-527119ce4939", + "faceitNickname": "skaterCS", + } + + +def test_games_from_profile(profile): + games = profile["games"].copy() + + profile["games"] = [] + res = tr.games_from_profile(profile) + assert res == [] + + profile["games"] = games[:1] + res = tr.games_from_profile(profile) + assert res == [ + { + "ctLeetifyRating": -0.0157, + "ctLeetifyRatingRounds": 12, + "dataSource": "faceit", + "elo": 1273, + "gameFinishedAt": "2024-01-13T20:45:53.000Z", + "gameId": "a3f0c4b6-da37-43c4-8679-b6b858ec1600", + "isCs2": True, + "mapName": "de_ancient", + "matchResult": "win", + "scores": "13-10", + "skillLevel": 6, + "tLeetifyRating": 0.1625, + "tLeetifyRatingRounds": 11, + "deaths": 11, + "hasBannedPlayer": False, + "kills": 19, + "partySize": 1, + "leetifyUserId": "6c53f87a-5877-4dd3-ab8f-527119ce4939", + } + ] + + profile["games"] = games + res = tr.games_from_profile(profile) + assert res == [ + { + "ctLeetifyRating": -0.0157, + "ctLeetifyRatingRounds": 12, + "dataSource": "faceit", + "elo": 1273, + "gameFinishedAt": "2024-01-13T20:45:53.000Z", + "gameId": "a3f0c4b6-da37-43c4-8679-b6b858ec1600", + "isCs2": True, + "mapName": "de_ancient", + "matchResult": "win", + "scores": "13-10", + "skillLevel": 6, + "tLeetifyRating": 0.1625, + "tLeetifyRatingRounds": 11, + "deaths": 11, + "hasBannedPlayer": False, + "kills": 19, + "partySize": 1, + "leetifyUserId": "6c53f87a-5877-4dd3-ab8f-527119ce4939", + }, + { + "ctLeetifyRating": -0.015, + "ctLeetifyRatingRounds": 6, + "dataSource": "faceit", + "elo": 1248, + "gameFinishedAt": "2024-01-13T00:51:26.000Z", + "gameId": "ba78c2f5-99b8-4d4d-afbd-cacee7894dbb", + "isCs2": True, + "mapName": "de_vertigo", + "matchResult": "win", + "scores": "13-5", + "skillLevel": 6, + "tLeetifyRating": 0.0715, + "tLeetifyRatingRounds": 12, + "deaths": 12, + "hasBannedPlayer": False, + "kills": 13, + "partySize": 1, + "leetifyUserId": "6c53f87a-5877-4dd3-ab8f-527119ce4939", + }, + { + "ctLeetifyRating": 0.0091, + "ctLeetifyRatingRounds": 12, + "dataSource": "faceit", + "elo": 1273, + "gameFinishedAt": "2024-01-13T00:11:36.000Z", + "gameId": "f57fc165-8d9d-4cbb-aeaf-3305bf96f6b1", + "isCs2": True, + "mapName": "de_anubis", + "matchResult": "loss", + "scores": "11-13", + "skillLevel": 6, + "tLeetifyRating": -0.0413, + "tLeetifyRatingRounds": 12, + "deaths": 17, + "hasBannedPlayer": False, + "kills": 12, + "partySize": 1, + "leetifyUserId": "6c53f87a-5877-4dd3-ab8f-527119ce4939", + }, + { + "ctLeetifyRating": 0.0273, + "ctLeetifyRatingRounds": 8, + "dataSource": "faceit", + "elo": 962, + "gameFinishedAt": "2023-11-12T19:53:56.000Z", + "gameId": "76bd9c1b-4350-4cba-a85c-853dda2319a3", + "isCs2": True, + "mapName": "de_vertigo", + "matchResult": "win", + "scores": "13-7", + "skillLevel": 4, + "tLeetifyRating": 0.0053, + "tLeetifyRatingRounds": 12, + "deaths": None, + "hasBannedPlayer": None, + "kills": None, + "partySize": None, + "leetifyUserId": "6c53f87a-5877-4dd3-ab8f-527119ce4939", + }, + { + "ctLeetifyRating": 0.0493, + "ctLeetifyRatingRounds": 21, + "dataSource": "faceit", + "elo": 910, + "gameFinishedAt": "2023-11-11T03:35:16.000Z", + "gameId": "fdd3867f-225b-4177-bc99-661a7fa43c41", + "isCs2": True, + "mapName": "de_vertigo", + "matchResult": "win", + "scores": "22-19", + "skillLevel": 4, + "tLeetifyRating": 0.0063, + "tLeetifyRatingRounds": 20, + "deaths": None, + "hasBannedPlayer": None, + "kills": None, + "partySize": None, + "leetifyUserId": "6c53f87a-5877-4dd3-ab8f-527119ce4939", + }, + { + "ctLeetifyRating": 0.0069, + "ctLeetifyRatingRounds": 12, + "dataSource": "faceit", + "elo": 960, + "gameFinishedAt": "2023-11-10T01:02:34.000Z", + "gameId": "73acee05-c6ce-4a15-9ab1-c4201443d6ff", + "isCs2": True, + "mapName": "de_mirage", + "matchResult": "loss", + "scores": "10-13", + "skillLevel": 4, + "tLeetifyRating": 0.0209, + "tLeetifyRatingRounds": 11, + "deaths": None, + "hasBannedPlayer": None, + "kills": None, + "partySize": None, + "leetifyUserId": "6c53f87a-5877-4dd3-ab8f-527119ce4939", + }, + ] + + +def test_player_stats_from_game(game): + stats = tr.player_stats_from_game(game) + assert stats == [ + { + "id": "f913fc05-40ff-4f55-b8b9-b46703317455", + "gameId": "a3f0c4b6-da37-43c4-8679-b6b858ec1600", + "gameFinishedAt": "2024-01-13T20:45:53.000Z", + "steam64Id": "76561198376400117", + "name": "TiMe_TrAvLeR", + "preaim": 8.5628, + "reactionTime": 0.75, + "accuracy": 0.2333, + "accuracyEnemySpotted": 0.4298, + "accuracyHead": 0.1774, + "shotsFiredEnemySpotted": 114, + "shotsFired": 270, + "shotsHitEnemySpotted": 49, + "shotsHitFriend": 0, + "shotsHitFriendHead": 0, + "shotsHitFoe": 63, + "shotsHitFoeHead": 0, + "utilityOnDeathAvg": 605.2632, + "heFoesDamageAvg": 14.25, + "heFriendsDamageAvg": 0, + "heThrown": 4, + "molotovThrown": 7, + "smokeThrown": 2, + "smokeThrownCT": 1, + "smokeThrownCTGood": 0, + "smokeThrownCTGoodRatio": 0, + "smokeThrownCTFoes": 0, + "counterStrafingShotsAll": 78, + "counterStrafingShotsBad": 10, + "counterStrafingShotsGood": 68, + "counterStrafingShotsGoodRatio": 0.8718, + "flashbangHitFoe": 0, + "flashbangLeadingToKill": 0, + "flashbangHitFoeAvgDuration": 0, + "flashbangHitFriend": 0, + "flashbangThrown": 0, + "flashAssist": 0, + "score": 39, + "initialTeamNumber": 3, + "mvps": 5, + "ctRoundsWon": 2, + "ctRoundsLost": 10, + "tRoundsWon": 8, + "tRoundsLost": 3, + "sprayAccuracy": 0.5405, + "molotovFoesDamageAvg": 1.2857, + "molotovFriendsDamageAvg": 0, + "color": 0, + "totalKills": 17, + "totalDeaths": 19, + "kdRatio": 0.89, + "multi2k": 3, + "multi3k": 2, + "multi4k": 0, + "multi5k": 0, + "hltvRating": 0.99, + "hsp": 0.5882, + "roundsSurvived": 4, + "roundsSurvivedPercentage": 0.1739, + "dpr": 84.3, + "totalAssists": 5, + "totalDamage": 1939, + "tradeKillOpportunities": 2, + "tradeKillAttempts": 1, + "tradeKillsSucceeded": 0, + "tradeKillAttemptsPercentage": 0.5, + "tradeKillsSuccessPercentage": 0, + "tradeKillOpportunitiesPerRound": 0.087, + "tradedDeathOpportunities": 4, + "tradedDeathAttempts": 2, + "tradedDeathAttemptsPercentage": 0.5, + "tradedDeathsSucceeded": 1, + "tradedDeathsSuccessPercentage": 0.5, + "tradedDeathsOpportunitiesPerRound": 0.1739, + "leetifyRating": 0.009, + "personalPerformanceRating": 0.0199, + "ctLeetifyRating": -0.021, + "tLeetifyRating": 0.0417, + "leetifyUserId": "8c3a9cb5-faaf-4401-ae9a-72f5e8528651", + "isCollector": False, + "isProPlan": True, + "isLeetifyStaff": False, + }, + { + "id": "6b39dfc3-3d7d-42d0-b69e-a56289b7bd41", + "gameId": "a3f0c4b6-da37-43c4-8679-b6b858ec1600", + "gameFinishedAt": "2024-01-13T20:45:53.000Z", + "steam64Id": "76561198801253208", + "name": "Huaran070314", + "preaim": 5.5644, + "reactionTime": 0.5156, + "accuracy": 0.1693, + "accuracyEnemySpotted": 0.47, + "accuracyHead": 0.2419, + "shotsFiredEnemySpotted": 100, + "shotsFired": 378, + "shotsHitEnemySpotted": 47, + "shotsHitFriend": 0, + "shotsHitFriendHead": 0, + "shotsHitFoe": 64, + "shotsHitFoeHead": 0, + "utilityOnDeathAvg": 166.6667, + "heFoesDamageAvg": 20.1111, + "heFriendsDamageAvg": 1.5556, + "heThrown": 9, + "molotovThrown": 6, + "smokeThrown": 7, + "smokeThrownCT": 2, + "smokeThrownCTGood": 1, + "smokeThrownCTGoodRatio": 0.5, + "smokeThrownCTFoes": 2, + "counterStrafingShotsAll": 89, + "counterStrafingShotsBad": 10, + "counterStrafingShotsGood": 79, + "counterStrafingShotsGoodRatio": 0.8876, + "flashbangHitFoe": 10, + "flashbangLeadingToKill": 0, + "flashbangHitFoeAvgDuration": 3.0426, + "flashbangHitFriend": 8, + "flashbangThrown": 16, + "flashAssist": 1, + "score": 54, + "initialTeamNumber": 3, + "mvps": 3, + "ctRoundsWon": 2, + "ctRoundsLost": 10, + "tRoundsWon": 8, + "tRoundsLost": 3, + "sprayAccuracy": 0.6389, + "molotovFoesDamageAvg": 5.6667, + "molotovFriendsDamageAvg": 0, + "color": 4, + "totalKills": 22, + "totalDeaths": 15, + "kdRatio": 1.47, + "multi2k": 4, + "multi3k": 2, + "multi4k": 0, + "multi5k": 0, + "hltvRating": 1.34, + "hsp": 0.6818, + "roundsSurvived": 8, + "roundsSurvivedPercentage": 0.3478, + "dpr": 109, + "totalAssists": 4, + "totalDamage": 2507, + "tradeKillOpportunities": 7, + "tradeKillAttempts": 5, + "tradeKillsSucceeded": 3, + "tradeKillAttemptsPercentage": 0.7143, + "tradeKillsSuccessPercentage": 0.6, + "tradeKillOpportunitiesPerRound": 0.35, + "tradedDeathOpportunities": 4, + "tradedDeathAttempts": 4, + "tradedDeathAttemptsPercentage": 1, + "tradedDeathsSucceeded": 2, + "tradedDeathsSuccessPercentage": 0.5, + "tradedDeathsOpportunitiesPerRound": 0.2, + "leetifyRating": 0.068, + "personalPerformanceRating": 0.0586, + "ctLeetifyRating": -0.0229, + "tLeetifyRating": 0.1672, + "leetifyUserId": None, + "isCollector": None, + "isProPlan": None, + "isLeetifyStaff": None, + }, + { + "id": "67050cd7-efe3-42ad-8d8e-4f0687dd3180", + "gameId": "a3f0c4b6-da37-43c4-8679-b6b858ec1600", + "gameFinishedAt": "2024-01-13T20:45:53.000Z", + "steam64Id": "76561198883031817", + "name": "RIPMASTERR", + "preaim": 8.3357, + "reactionTime": 0.5781, + "accuracy": 0.2, + "accuracyEnemySpotted": 0.382, + "accuracyHead": 0.1163, + "shotsFiredEnemySpotted": 89, + "shotsFired": 225, + "shotsHitEnemySpotted": 34, + "shotsHitFriend": 0, + "shotsHitFriendHead": 0, + "shotsHitFoe": 45, + "shotsHitFoeHead": 0, + "utilityOnDeathAvg": 435.2941, + "heFoesDamageAvg": 5.2, + "heFriendsDamageAvg": 0, + "heThrown": 5, + "molotovThrown": 9, + "smokeThrown": 11, + "smokeThrownCT": 7, + "smokeThrownCTGood": 2, + "smokeThrownCTGoodRatio": 0.2857, + "smokeThrownCTFoes": 2, + "counterStrafingShotsAll": 29, + "counterStrafingShotsBad": 9, + "counterStrafingShotsGood": 20, + "counterStrafingShotsGoodRatio": 0.6897, + "flashbangHitFoe": 0, + "flashbangLeadingToKill": 0, + "flashbangHitFoeAvgDuration": 0, + "flashbangHitFriend": 0, + "flashbangThrown": 0, + "flashAssist": 0, + "score": 34, + "initialTeamNumber": 3, + "mvps": 0, + "ctRoundsWon": 2, + "ctRoundsLost": 10, + "tRoundsWon": 8, + "tRoundsLost": 3, + "sprayAccuracy": 0.2, + "molotovFoesDamageAvg": 0.7778, + "molotovFriendsDamageAvg": 0, + "color": 3, + "totalKills": 12, + "totalDeaths": 17, + "kdRatio": 0.71, + "multi2k": 1, + "multi3k": 0, + "multi4k": 0, + "multi5k": 0, + "hltvRating": 0.67, + "hsp": 0.3333, + "roundsSurvived": 6, + "roundsSurvivedPercentage": 0.2609, + "dpr": 52.83, + "totalAssists": 3, + "totalDamage": 1215, + "tradeKillOpportunities": 6, + "tradeKillAttempts": 4, + "tradeKillsSucceeded": 3, + "tradeKillAttemptsPercentage": 0.6667, + "tradeKillsSuccessPercentage": 0.75, + "tradeKillOpportunitiesPerRound": 0.2609, + "tradedDeathOpportunities": 7, + "tradedDeathAttempts": 7, + "tradedDeathAttemptsPercentage": 1, + "tradedDeathsSucceeded": 2, + "tradedDeathsSuccessPercentage": 0.2857, + "tradedDeathsOpportunitiesPerRound": 0.3043, + "leetifyRating": -0.0432, + "personalPerformanceRating": -0.0347, + "ctLeetifyRating": -0.0801, + "tLeetifyRating": -0.003, + "leetifyUserId": "b94bd18e-9bb3-4150-aa5a-596adfe29103", + "isCollector": False, + "isProPlan": False, + "isLeetifyStaff": False, + }, + ]