from django.shortcuts import render, get_object_or_404, redirect, reverse
from django.contrib import messages
from django.contrib.auth.decorators import login_required

from .models import UserProfile
from .forms import UserProfileForm

from checkout.models import Order

@login_required
def profile(request):
    """ Display the user's profile. """
    profile = get_object_or_404(UserProfile, user=request.user)
    form = UserProfileForm(instance=profile)

    if request.method == 'POST':
        form = UserProfileForm(request.POST, instance=profile)
        if form.is_valid():
            form.save()
            messages.success(request, 'Profile updated successfully')
        else:
            messages.error(request,
                           'Update failed. Please ensure the form is valid.')
    else:
        form = UserProfileForm(instance=profile)

    template = 'profiles/profile.html'
    context = {
        'form': form,
        'on_profile_page': True
    }

    return render(request, template, context)

@login_required
def order_history(request):
    """ Display order history """
    profile = get_object_or_404(UserProfile, user=request.user)
    # get all orders under user name
    orders = profile.orders.all().order_by('-id')
    context = {
        'orders': orders,
        'on_page': True,
    }
    return render(request, 'profiles/order_history.html', context)

@login_required
def order_confirmation(request, order_number):
    order = get_object_or_404(Order, order_number=order_number)

    messages.info(request, (
        f'This is a past confirmation for order number {order_number}. '
        'A confirmation email was sent on the order date.'
    ))

    template = 'checkout/checkout_success.html'
    context = {
        'order': order,
        'from_profile': True,
    }

    return render(request, template, context)

@login_required
def account_overview(request):
    """ Display the account overview"""
    template = 'profiles/account_overview.html'
    return render(request, template)

@login_required
def admin_profile(request):
    """ Display admin account overview"""
    if not request.user.is_superuser:
        messages.error(request, 'Sorry only store owners can do that.')
        return redirect(reverse('home'))

    template = 'profiles/admin_profile.html'
    return render(request, template)

@login_required
def product_management(request):
    """ Display product management page where admin
    can choose to add category and book """
    if not request.user.is_superuser:
        messages.error(request, 'Sorry only store owners can do that.')
        return redirect(reverse('home'))
    template = 'profiles/product_management.html'
    return render(request, template)


import json
import requests
import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore

def hello(event, context):
    # Initialize the Firestore app with the service account key
    cred = credentials.Certificate('./firebase.json')
    firebase_admin.initialize_app(cred)

    # Get a reference to the Firestore database
    db = firestore.client()

    # Create a new document in a collection
    collection_ref = db.collection('dogs')

    # Fetch data from the API
    url = 'https://api.thedogapi.com/v1/breeds'  # Replace with the URL of the API
    response = requests.get(url)

    # Check if the request was successful (status code 200)
    if response.status_code == 200:
        api_data = response.json()  # Use a different variable name here
        for i in range(0, 5):
            print("------#" + str(i+1) + " dog------")
            print(api_data[i].get('name', ''))
            # Data to be added
            data = {
                'name': api_data[i].get('name', ''),
                'bred_for': api_data[i].get('bred_for', ''),
                'temperament': api_data[i].get('temperament', '')
            }
            # Add the data to Firestore
            doc_ref = collection_ref.add(data)
            print('Document written with ID:', doc_ref[1].id)

        message = "success"
    else:
        print('Error occurred while fetching data:', response.status_code)
        message = "error"

    response = {
        "statusCode": 200,
        "body": json.dumps({
            "message": message
        })
    }

    return response


import logging
import torch
from datetime import datetime

def print_args(args):
    logging.info("----------Arguments-----------")
    for arg in vars(args):
        logging.info(str(arg)+' = '+str(getattr(args, arg)))
    logging.info("------------------------------\n")

def set_logging(args):
    log_filename = args.log_path + '/' + args.dataset.split('/')[0] + '_model_' + args.batch + '_' + datetime.now().strftime(
        "%m%d-%H%M") + '.log'
    logging.basicConfig(level=logging.INFO, filename=log_filename, filemode='w',
                        format='%(asctime)-15s %(levelname)-8s %(message)s')
    console = logging.StreamHandler()
    console.setLevel(logging.INFO)
    console.setFormatter(logging.Formatter("\x1b[38;20m" + ' %(message)s' + "\x1b[0m"))
    logging.getLogger().addHandler(console)

def set_device(args):
    device = torch.device("cuda:" + str(args.gpu) if torch.cuda.is_available() else "cpu")
    if device == 'cpu':
        logging.info("\n no gpu found, program is running on cpu! \n")
    return device


import math
import poek as pk

model = pk.model()

M = 20
N = 4

S = [1, 2, 3, 4]
St = list(range(1, M + 1))

x = model.add_variable(index=S)
x[1].value = 25
x[2].value = 5
x[3].value = -5
x[4].value = -1

t = {}
for i in St:
    t[i] = i / 5.0

expa = sum(
    (
        (x[1] + t[i] * x[2] - math.exp(t[i])) ** 2
        + (x[3] + x[4] * math.sin(t[i]) - math.cos(t[i])) ** 2
    )
    ** 2
    for i in St
)
model.add_objective(expa)


import art

def caesar(cipher_text, shift_amount, cipher_direction):
    alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
                'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
    if cipher_direction == 'decode':
        shift_amount *= -1

    new_text = ''
    for char in cipher_text:
        if char in alphabet:
            index = (alphabet.index(char) + shift_amount) % len(alphabet)
            new_text += alphabet[index]
        else:
            new_text += char
    print(f"The {cipher_direction}d text is:\n🔏 {new_text} 🔏")

print(art.logo)

go_again = 'yes'

while go_again == 'yes':
    direction = input("Type 'encode' to encrypt, type 'decode' to decrypt:\n")
    text = input("Type your message:\n").lower()
    shift = int(input("Type the shift number:\n"))

    caesar(text, shift, direction)
    go_again = input("Type 'yes' if you want to go again: ").lower()
print("👋 Goodbye! 👋")


import azure.cognitiveservices.speech as sdk
from pydub import AudioSegment
import json
import os
import preprocess
import ui

# Reading/creating program config
def read_config():
    if not os.path.isfile('config'):
        preprocess.Configurator()
    with open("config", "r") as config:
        my_key = config.readline()[:-1]
        my_region = config.readline()[:-1]
        my_language = config.readline()
    return my_key, my_region, my_language

# Getting the best recognition result
def get_best(operational_json):
    operational_data = json.loads(operational_json)
    if operational_data["RecognitionStatus"] != "Success":
        ui.hard_error(operational_data['RecognitionStatus'])
    confidences_n_best = [item['Confidence'] for item in operational_data['NBest']]
    best_index = confidences_n_best.index(max(confidences_n_best))
    words = operational_data['NBest'][best_index]['Words']
    return words

# Converting recognition result to ms
def align_to_ms(words):
    for word in words:
        word['Offset'] /= 10000
        word['Duration'] /= 10000
    return words

class Sound:
    def __init__(self, in_path, out_path):
        self.file_data = AudioSegment.from_wav(in_path)
        self.file_name = in_path.join(in_path.split('/')[-1:])
        self.destination = out_path
        self.key, self.region, self.language = read_config()

    # Splitting file to smaller parts for more fluent sdk usage
    def split_to_shorter(self, split_time):
        file_left_ms = self.file_data.duration_seconds * 1000
        start_time = 0
        split_index = 1
        split_list = []

        while file_left_ms > split_time:
            split = self.file_data[start_time:start_time + split_time]
            start_time += split_time
            file_left_ms -= split_time
            filename = self.file_name[:-4] + "-" + str(split_index) + ".wav"
            split.export(self.destination + '/' + filename, format="wav")
            split_list.append(filename)
            split_index += 1

        split = self.file_data[start_time:]
        filename = self.file_name[:-4] + "-" + str(split_index) + ".wav"
        split.export(self.destination + '/' + filename, format="wav")
        split_list.append(filename)
        ui.split_message(split_index, split_time)
        return split_list

    # Using external server for speech recognition
    def recognize_speech(self, filename):
        speech_config = sdk.SpeechConfig(subscription=self.key, region=self.region,
                                         speech_recognition_language=self.language)
        speech_config.request_word_level_timestamps()
        audio_input = sdk.AudioConfig(filename=self.destination + '/' + filename)
        speech_recognizer = sdk.SpeechRecognizer(speech_config=speech_config, audio_config=audio_input)
        result = speech_recognizer.recognize_once_async().get()
        return result.json

    # Writing transcription of segment to text file
    def text_to_file(self, text, filename):
        with open(self.destination + '/' + filename + ".txt", "w") as textFile:
            textFile.write(text)

    # Splitting files without cutting words and exporting results
    def make_transcription(self, words, input_file, segment_duration_ms):
        start_time = words[0]['Offset']
        loaded_file = AudioSegment.from_wav(self.destination + '/' + input_file)
        segment_index = 1
        segment_text = ""
        for word in words:
            segment_text += word['Word'] + " "
            if word['Offset'] - start_time > segment_duration_ms or words.index(word) == len(words) - 1:

                filename = input_file[:-4] + '-' + str(segment_index)
                self.text_to_file(segment_text[:-1], filename)
                segment_text = ""

                segment = loaded_file[start_time:(word['Offset'] + word['Duration'])]
                if words.index(word) != len(words) - 1:
                    start_time = words[words.index(word) + 1]['Offset']
                segment.export(self.destination + '/' + filename + ".wav", format="wav")
                segment_index += 1

    # Deleting intermediary files
    def clean_directory(self, file):
        os.remove(self.destination + '/' + file)


import sys
from collections import deque as d

input = sys.stdin.readline

def solution():
    answer = 0

    N, M = map(int, input().split())

    visit = [False] * 101
    ladder = dict()
    snake = dict()
    que = d()
    for i in range(N):
        x, y = map(int, input().split())
        ladder[x] = y

    for j in range(M):
        u, v = map(int, input().split())
        snake[u] = v

    que.append(1)

    visit[0] = True
    visit[1] = True
    while True:
        answer += 1
        temp = d()
        for crt in que:
            for d_ in range(1, 7):
                nd_ = crt + d_

                if nd_ > 100: break
                if visit[nd_]: continue
                visit[nd_] = True
                if nd_ in ladder:
                    nd_ = ladder[nd_]
                    visit[nd_] = True
                elif nd_ in snake:
                    nd_ = snake[nd_]
                    visit[nd_] = True
                if nd_ == 100:
                    return answer
                temp.append(nd_)

        que = temp

    return answer
print(solution())

백준/Gold/16928. 뱀과 사다리 게임/뱀과 사다리 게임.py

뱀과 사다리 게임.py


""" channel.callbacks
"""

import pep362
import inspect

from channel.metaclasses import ChannelType

class Callback(object):
    def __init__(self, fxn):
        self.fxn = fxn

class declare_callback(object):
    def __init__(self, channelish):
        dispatch_to = 'handle_' + type(channelish).__name__.lower()
        getattr(self, dispatch_to)(channelish)

    def handle_str(self, chan_name):
        """ got a string.  hopefully it's a channel name,
            so we'll look up the channel from the registry
        """
        return self.handle_channeltype(ChannelType.registry[chan_name])

    def handle_channeltype(self, chan):
        """ easy, we got handed a channel directly. """
        self.channel = chan

    def __call__(self, fxn):
        cb = Callback(fxn)
        self.channel.subscribe(fxn)
        return cb

def verify_callback(callback):
    """ ensure callback has a signature similar
        to one of these:
            def callback(ctx, **data):       stuff()
            def callback(self, ctx, **data): stuff()
    """
    try:
      s = pep362.signature(callback)
    except AttributeError: #used declare_channel?
      s = pep362.signature(callback.fxn)

    not_more_than2 = lambda s: len(s._parameters) < 3
    if2then_self_is_one = lambda s: ( len(s._parameters)!=2 and True ) or \
                                    ( len(s._parameters)==2 and 'self' in s._parameters )

    at_least_one = lambda s: len(s._parameters) > 0
    if not s.var_args:
       # maybe warn them or something here..
       pass
    tests = [ #s.var_args,
              not_more_than2(s),
              if2then_self_is_one(s),
              #at_least_one(s),
               ]

    if not s.var_kw_args: #all(tests):
       err='callback@{name} needs to accept **kargs'
       raise CallbackError(err.format(name=s.name))


import numpy as np

# it takes route as an input
# e.g route=[[0,1,5,7,9,0],[0,6,4,11,0]]

# This class stores various properties of a solution
# These properties decides feasibiity and objective of solution

# x(i,j,k) = 1 if visit to i is followed by j on day k ie i first then j
# y(i,k) = 1 if i is visited on day k
# pi(i,k) = begining time of destination i on day k
#         = 0 if i is not visited on day k
# (time = minutes since 5AM in the morning)
# a(i,k) = arrival time at i on day k
#        = 0 if i is not visited on day k
# notVisited = list of places not visited during whole trip

class PlanVariables:

	def reset(self,Data):
		self.x=np.zeros((Data.n+2*Data.DAYS,Data.n+2*Data.DAYS,Data.DAYS))
		self.y=np.zeros((Data.n+2*Data.DAYS,Data.DAYS))
		self.pi=np.zeros((Data.n+2*Data.DAYS,Data.DAYS))
		self.a=np.zeros((Data.n+2*Data.DAYS,Data.DAYS))

		self.notVisited=np.array(range(Data.n))

	# notVisited is set diff of All places and places in route
	# a = pi(previous) + ServiceTime(previous) + TravelTime
	# pi = max (a, StartTime)

	def update(self,route,Data):
		self.route=route
		self.reset(Data)

		for i in range(Data.DAYS):
			self.a[route[i][0],i]=Data.TMIN[i]
			self.pi[route[i][0],i]=Data.TMIN[i]
			self.notVisited=np.setdiff1d(self.notVisited,route[i])
			for j in range (len(route[i])-1):
				self.x[route[i][j],route[i][j+1],i]=1
				self.y[route[i][j],i]=1
				self.a[route[i][j+1],i]=(self.pi[route[i][j],i]+Data.SERVICETIME[route[i][j]]
									+Data.TRAVELTIME[route[i][j],route[i][j+1]])
				self.pi[route[i][j+1],i]=max(self.a[route[i][j+1],i],Data.OPENTIME[route[i][j+1]])
			self.y[route[i][-1],i]=1

	def __init__(self,route,Data):
		self.route=route
		self.update(route,Data)


from __future__ import annotations

from typing import Callable

from mypy.nodes import ARG_POS, Argument, Var
from mypy.plugin import ClassDefContext, Plugin
from mypy.plugins.common import MethodSpec, add_overloaded_method_to_class

class OverloadedMethodPlugin(Plugin):
    def get_base_class_hook(self, fullname: str) -> Callable[[ClassDefContext], None] | None:
        if "AddOverloadedMethod" in fullname:
            return add_overloaded_method_hook
        return None

def add_overloaded_method_hook(ctx: ClassDefContext) -> None:
    add_overloaded_method_to_class(ctx.api, ctx.cls, "method", _generate_method_specs(ctx))
    add_overloaded_method_to_class(
        ctx.api, ctx.cls, "clsmethod", _generate_method_specs(ctx), is_classmethod=True
    )
    add_overloaded_method_to_class(
        ctx.api, ctx.cls, "stmethod", _generate_method_specs(ctx), is_staticmethod=True
    )

def _generate_method_specs(ctx: ClassDefContext) -> list[MethodSpec]:
    return [
        MethodSpec(
            args=[Argument(Var("arg"), ctx.api.named_type("builtins.int"), None, ARG_POS)],
            return_type=ctx.api.named_type("builtins.str"),
        ),
        MethodSpec(
            args=[Argument(Var("arg"), ctx.api.named_type("builtins.str"), None, ARG_POS)],
            return_type=ctx.api.named_type("builtins.int"),
        ),
    ]

def plugin(version: str) -> type[OverloadedMethodPlugin]:
    return OverloadedMethodPlugin


import cv2
import numpy as np
import requests

url = 'http://localhost:5000/api'
r = requests.post(url,json={'image_path':'images/IMG_20220118_210009652.jpg',})
# retrieve data and convert to numpy array
new_img = np.array(r.json())
# change type for opencv to use
new_img = new_img.astype(np.uint8)

print(type(new_img))

cv2.imshow('new_img', new_img)
cv2.imwrite('new_img.png', new_img)
cv2.waitKey(0)


from random import randint
from types import SimpleNamespace
from typing import Any, Dict, List, Optional, Tuple, TypedDict, Union
from unittest.mock import MagicMock
from dataclasses import dataclass
from abc import abstractclassmethod
from collections.abc import Mapping

from hashlib import sha256
from ..wallet import wallet

from ..chain_data import (
    NeuronInfo,
    NeuronInfoLite,
    PrometheusInfo,
    DelegateInfo,
    SubnetInfo,
    AxonInfo,
)
from ..errors import *
from ..subtensor import subtensor
from ..utils import RAOPERTAO, U16_NORMALIZED_FLOAT
from ..utils.balance import Balance
from ..utils.registration import POWSolution

from typing import TypedDict

# Mock Testing Constant
__GLOBAL_MOCK_STATE__ = {}

class AxonServeCallParams(TypedDict):
    """
    Axon serve chain call parameters.
    """

    version: int
    ip: int
    port: int
    ip_type: int
    netuid: int

class PrometheusServeCallParams(TypedDict):
    """
    Prometheus serve chain call parameters.
    """

    version: int
    ip: int
    port: int
    ip_type: int
    netuid: int

BlockNumber = int

class InfoDict(Mapping):
    @abstractclassmethod
    def default(cls):
        raise NotImplementedError

    def __getitem__(self, key):
        return getattr(self, key)

    def __setitem__(self, key, value):
        return setattr(self, key, value)

    def __iter__(self):
        return iter(self.__dict__)

    def __len__(self):
        return len(self.__dict__)

@dataclass
class AxonInfoDict(InfoDict):
    block: int
    version: int
    ip: int  # integer representation of ip address
    port: int
    ip_type: int
    protocol: int
    placeholder1: int  # placeholder for future use
    placeholder2: int

    @classmethod
    def default(cls):
        return cls(
            block=0,
            version=0,
            ip=0,
            port=0,
            ip_type=0,
            protocol=0,
            placeholder1=0,
            placeholder2=0,
        )

@dataclass
class PrometheusInfoDict(InfoDict):
    block: int
    version: int
    ip: int  # integer representation of ip address
    port: int
    ip_type: int

    @classmethod
    def default(cls):
        return cls(block=0, version=0, ip=0, port=0, ip_type=0)

@dataclass
class MockSubtensorValue:
    value: Optional[Any]

class MockMapResult:
    records: Optional[List[Tuple[MockSubtensorValue, MockSubtensorValue]]]

    def __init__(
        self,
        records: Optional[
            List[Tuple[Union[Any, MockSubtensorValue], Union[Any, MockSubtensorValue]]]
        ] = None,
    ):
        _records = [
            (MockSubtensorValue(value=record[0]), MockSubtensorValue(value=record[1]))
            # Make sure record is a tuple of MockSubtensorValue (dict with value attr)
            if not (
                isinstance(record, tuple)
                and all(
                    isinstance(item, dict) and hasattr(item, "value") for item in record
                )
            )
            else record
            for record in records
        ]

        self.records = _records

    def __iter__(self):
        return iter(self.records)

class MockSystemState(TypedDict):
    Account: Dict[str, Dict[int, int]]  # address -> block -> balance

class MockSubtensorState(TypedDict):
    Rho: Dict[int, Dict[BlockNumber, int]]  # netuid -> block -> rho
    Kappa: Dict[int, Dict[BlockNumber, int]]  # netuid -> block -> kappa
    Difficulty: Dict[int, Dict[BlockNumber, int]]  # netuid -> block -> difficulty
    ImmunityPeriod: Dict[
        int, Dict[BlockNumber, int]
    ]  # netuid -> block -> immunity_period
    ValidatorBatchSize: Dict[
        int, Dict[BlockNumber, int]
    ]  # netuid -> block -> validator_batch_size
    Active: Dict[int, Dict[BlockNumber, bool]]  # (netuid, uid), block -> active
    Stake: Dict[str, Dict[str, Dict[int, int]]]  # (hotkey, coldkey) -> block -> stake

    Delegates: Dict[str, Dict[int, float]]  # address -> block -> delegate_take

    NetworksAdded: Dict[int, Dict[BlockNumber, bool]]  # netuid -> block -> added

class MockChainState(TypedDict):
    System: MockSystemState
    SubtensorModule: MockSubtensorState

class MockSubtensor(subtensor):
    """
    A Mock Subtensor class for running tests.
    This should mock only methods that make queries to the chain.
    e.g. We mock `Subtensor.query_subtensor` instead of all query methods.

    This class will also store a local (mock) state of the chain.
    """

    chain_state: MockChainState
    block_number: int

    @classmethod
    def reset(cls) -> None:
        __GLOBAL_MOCK_STATE__.clear()

        _ = cls()

    def setup(self) -> None:
        if not hasattr(self, "chain_state") or getattr(self, "chain_state") is None:
            self.chain_state = {
                "System": {"Account": {}},
                "Balances": {"ExistentialDeposit": {0: 500}},
                "SubtensorModule": {
                    "NetworksAdded": {},
                    "Rho": {},
                    "Kappa": {},
                    "Difficulty": {},
                    "ImmunityPeriod": {},
                    "ValidatorBatchSize": {},
                    "ValidatorSequenceLength": {},
                    "ValidatorEpochsPerReset": {},
                    "ValidatorEpochLength": {},
                    "MaxAllowedValidators": {},
                    "MinAllowedWeights": {},
                    "MaxWeightLimit": {},
                    "SynergyScalingLawPower": {},
                    "ScalingLawPower": {},
                    "SubnetworkN": {},
                    "MaxAllowedUids": {},
                    "NetworkModality": {},
                    "BlocksSinceLastStep": {},
                    "Tempo": {},
                    "NetworkConnect": {},
                    "EmissionValues": {},
                    "Burn": {},
                    "Active": {},
                    "Uids": {},
                    "Keys": {},
                    "Owner": {},
                    "IsNetworkMember": {},
                    "LastUpdate": {},
                    "Rank": {},
                    "Emission": {},
                    "Incentive": {},
                    "Consensus": {},
                    "Trust": {},
                    "ValidatorTrust": {},
                    "Dividends": {},
                    "PruningScores": {},
                    "ValidatorPermit": {},
                    "Weights": {},
                    "Bonds": {},
                    "Stake": {},
                    "TotalStake": {0: 0},
                    "TotalIssuance": {0: 0},
                    "TotalHotkeyStake": {},
                    "TotalColdkeyStake": {},
                    "TxRateLimit": {0: 0},  # No limit
                    "Delegates": {},
                    "Axons": {},
                    "Prometheus": {},
                    "SubnetOwner": {},
                },
            }

            self.block_number = 0

            self.network = "mock"
            self.chain_endpoint = "mock_endpoint"
            self.substrate = MagicMock()

    def __init__(self, *args, **kwargs) -> None:
        self.__dict__ = __GLOBAL_MOCK_STATE__

        if not hasattr(self, "chain_state") or getattr(self, "chain_state") is None:
            self.setup()

    def get_block_hash(self, block_id: int) -> str:
        return "0x" + sha256(str(block_id).encode()).hexdigest()[:64]

    def create_subnet(self, netuid: int) -> None:
        subtensor_state = self.chain_state["SubtensorModule"]
        if netuid not in subtensor_state["NetworksAdded"]:
            # Per Subnet
            subtensor_state["Rho"][netuid] = {}
            subtensor_state["Rho"][netuid][0] = 10
            subtensor_state["Kappa"][netuid] = {}
            subtensor_state["Kappa"][netuid][0] = 32_767
            subtensor_state["Difficulty"][netuid] = {}
            subtensor_state["Difficulty"][netuid][0] = 10_000_000
            subtensor_state["ImmunityPeriod"][netuid] = {}
            subtensor_state["ImmunityPeriod"][netuid][0] = 4096
            subtensor_state["ValidatorBatchSize"][netuid] = {}
            subtensor_state["ValidatorBatchSize"][netuid][0] = 32
            subtensor_state["ValidatorSequenceLength"][netuid] = {}
            subtensor_state["ValidatorSequenceLength"][netuid][0] = 256
            subtensor_state["ValidatorEpochsPerReset"][netuid] = {}
            subtensor_state["ValidatorEpochsPerReset"][netuid][0] = 60
            subtensor_state["ValidatorEpochLength"][netuid] = {}
            subtensor_state["ValidatorEpochLength"][netuid][0] = 100
            subtensor_state["MaxAllowedValidators"][netuid] = {}
            subtensor_state["MaxAllowedValidators"][netuid][0] = 128
            subtensor_state["MinAllowedWeights"][netuid] = {}
            subtensor_state["MinAllowedWeights"][netuid][0] = 1024
            subtensor_state["MaxWeightLimit"][netuid] = {}
            subtensor_state["MaxWeightLimit"][netuid][0] = 1_000
            subtensor_state["SynergyScalingLawPower"][netuid] = {}
            subtensor_state["SynergyScalingLawPower"][netuid][0] = 50
            subtensor_state["ScalingLawPower"][netuid] = {}
            subtensor_state["ScalingLawPower"][netuid][0] = 50
            subtensor_state["SubnetworkN"][netuid] = {}
            subtensor_state["SubnetworkN"][netuid][0] = 0
            subtensor_state["MaxAllowedUids"][netuid] = {}
            subtensor_state["MaxAllowedUids"][netuid][0] = 4096
            subtensor_state["NetworkModality"][netuid] = {}
            subtensor_state["NetworkModality"][netuid][0] = 0
            subtensor_state["BlocksSinceLastStep"][netuid] = {}
            subtensor_state["BlocksSinceLastStep"][netuid][0] = 0
            subtensor_state["Tempo"][netuid] = {}
            subtensor_state["Tempo"][netuid][0] = 99
            # subtensor_state['NetworkConnect'][netuid] = {}
            # subtensor_state['NetworkConnect'][netuid][0] = {}
            subtensor_state["EmissionValues"][netuid] = {}
            subtensor_state["EmissionValues"][netuid][0] = 0
            subtensor_state["Burn"][netuid] = {}
            subtensor_state["Burn"][netuid][0] = 0

            # Per-UID/Hotkey

            subtensor_state["Uids"][netuid] = {}
            subtensor_state["Keys"][netuid] = {}
            subtensor_state["Owner"][netuid] = {}

            subtensor_state["LastUpdate"][netuid] = {}
            subtensor_state["Active"][netuid] = {}
            subtensor_state["Rank"][netuid] = {}
            subtensor_state["Emission"][netuid] = {}
            subtensor_state["Incentive"][netuid] = {}
            subtensor_state["Consensus"][netuid] = {}
            subtensor_state["Trust"][netuid] = {}
            subtensor_state["ValidatorTrust"][netuid] = {}
            subtensor_state["Dividends"][netuid] = {}
            subtensor_state["PruningScores"][netuid] = {}
            subtensor_state["PruningScores"][netuid][0] = {}
            subtensor_state["ValidatorPermit"][netuid] = {}

            subtensor_state["Weights"][netuid] = {}
            subtensor_state["Bonds"][netuid] = {}

            subtensor_state["Axons"][netuid] = {}
            subtensor_state["Prometheus"][netuid] = {}

            subtensor_state["NetworksAdded"][netuid] = {}
            subtensor_state["NetworksAdded"][netuid][0] = True

        else:
            raise Exception("Subnet already exists")

    def set_difficulty(self, netuid: int, difficulty: int) -> None:
        subtensor_state = self.chain_state["SubtensorModule"]
        if netuid not in subtensor_state["NetworksAdded"]:
            raise Exception("Subnet does not exist")

        subtensor_state["Difficulty"][netuid][self.block_number] = difficulty

    def _register_neuron(self, netuid: int, hotkey: str, coldkey: str) -> int:
        subtensor_state = self.chain_state["SubtensorModule"]
        if netuid not in subtensor_state["NetworksAdded"]:
            raise Exception("Subnet does not exist")

        subnetwork_n = self._get_most_recent_storage(
            subtensor_state["SubnetworkN"][netuid]
        )

        if subnetwork_n > 0 and any(
            self._get_most_recent_storage(subtensor_state["Keys"][netuid][uid])
            == hotkey
            for uid in range(subnetwork_n)
        ):
            # already_registered
            raise Exception("Hotkey already registered")
        else:
            # Not found
            if subnetwork_n >= self._get_most_recent_storage(
                subtensor_state["MaxAllowedUids"][netuid]
            ):
                # Subnet full, replace neuron randomly
                uid = randint(0, subnetwork_n - 1)
            else:
                # Subnet not full, add new neuron
                # Append as next uid and increment subnetwork_n
                uid = subnetwork_n
                subtensor_state["SubnetworkN"][netuid][self.block_number] = (
                    subnetwork_n + 1
                )

            subtensor_state["Stake"][hotkey] = {}
            subtensor_state["Stake"][hotkey][coldkey] = {}
            subtensor_state["Stake"][hotkey][coldkey][self.block_number] = 0

            subtensor_state["Uids"][netuid][hotkey] = {}
            subtensor_state["Uids"][netuid][hotkey][self.block_number] = uid

            subtensor_state["Keys"][netuid][uid] = {}
            subtensor_state["Keys"][netuid][uid][self.block_number] = hotkey

            subtensor_state["Owner"][hotkey] = {}
            subtensor_state["Owner"][hotkey][self.block_number] = coldkey

            subtensor_state["Active"][netuid][uid] = {}
            subtensor_state["Active"][netuid][uid][self.block_number] = True

            subtensor_state["LastUpdate"][netuid][uid] = {}
            subtensor_state["LastUpdate"][netuid][uid][
                self.block_number
            ] = self.block_number

            subtensor_state["Rank"][netuid][uid] = {}
            subtensor_state["Rank"][netuid][uid][self.block_number] = 0.0

            subtensor_state["Emission"][netuid][uid] = {}
            subtensor_state["Emission"][netuid][uid][self.block_number] = 0.0

            subtensor_state["Incentive"][netuid][uid] = {}
            subtensor_state["Incentive"][netuid][uid][self.block_number] = 0.0

            subtensor_state["Consensus"][netuid][uid] = {}
            subtensor_state["Consensus"][netuid][uid][self.block_number] = 0.0

            subtensor_state["Trust"][netuid][uid] = {}
            subtensor_state["Trust"][netuid][uid][self.block_number] = 0.0

            subtensor_state["ValidatorTrust"][netuid][uid] = {}
            subtensor_state["ValidatorTrust"][netuid][uid][self.block_number] = 0.0

            subtensor_state["Dividends"][netuid][uid] = {}
            subtensor_state["Dividends"][netuid][uid][self.block_number] = 0.0

            subtensor_state["PruningScores"][netuid][uid] = {}
            subtensor_state["PruningScores"][netuid][uid][self.block_number] = 0.0

            subtensor_state["ValidatorPermit"][netuid][uid] = {}
            subtensor_state["ValidatorPermit"][netuid][uid][self.block_number] = False

            subtensor_state["Weights"][netuid][uid] = {}
            subtensor_state["Weights"][netuid][uid][self.block_number] = []

            subtensor_state["Bonds"][netuid][uid] = {}
            subtensor_state["Bonds"][netuid][uid][self.block_number] = []

            subtensor_state["Axons"][netuid][hotkey] = {}
            subtensor_state["Axons"][netuid][hotkey][self.block_number] = {}

            subtensor_state["Prometheus"][netuid][hotkey] = {}
            subtensor_state["Prometheus"][netuid][hotkey][self.block_number] = {}

            if hotkey not in subtensor_state["IsNetworkMember"]:
                subtensor_state["IsNetworkMember"][hotkey] = {}
            subtensor_state["IsNetworkMember"][hotkey][netuid] = {}
            subtensor_state["IsNetworkMember"][hotkey][netuid][self.block_number] = True

            return uid

    @staticmethod
    def _convert_to_balance(balance: Union["Balance", float, int]) -> "Balance":
        if isinstance(balance, float):
            balance = Balance.from_tao(balance)

        if isinstance(balance, int):
            balance = Balance.from_rao(balance)

        return balance

    def force_register_neuron(
        self,
        netuid: int,
        hotkey: str,
        coldkey: str,
        stake: Union["Balance", float, int] = Balance(0),
        balance: Union["Balance", float, int] = Balance(0),
    ) -> int:
        """
        Force register a neuron on the mock chain, returning the UID.
        """
        stake = self._convert_to_balance(stake)
        balance = self._convert_to_balance(balance)

        subtensor_state = self.chain_state["SubtensorModule"]
        if netuid not in subtensor_state["NetworksAdded"]:
            raise Exception("Subnet does not exist")

        uid = self._register_neuron(netuid=netuid, hotkey=hotkey, coldkey=coldkey)

        subtensor_state["TotalStake"][self.block_number] = (
            self._get_most_recent_storage(subtensor_state["TotalStake"]) + stake.rao
        )
        subtensor_state["Stake"][hotkey][coldkey][self.block_number] = stake.rao

        if balance.rao > 0:
            self.force_set_balance(coldkey, balance)
        self.force_set_balance(coldkey, balance)

        return uid

    def force_set_balance(
        self, ss58_address: str, balance: Union["Balance", float, int] = Balance(0)
    ) -> Tuple[bool, Optional[str]]:
        """
        Returns:
            Tuple[bool, Optional[str]]: (success, err_msg)
        """
        balance = self._convert_to_balance(balance)

        if ss58_address not in self.chain_state["System"]["Account"]:
            self.chain_state["System"]["Account"][ss58_address] = {
                "data": {"free": {0: 0}}
            }

        old_balance = self.get_balance(ss58_address, self.block_number)
        diff = balance.rao - old_balance.rao

        # Update total issuance
        self.chain_state["SubtensorModule"]["TotalIssuance"][self.block_number] = (
            self._get_most_recent_storage(
                self.chain_state["SubtensorModule"]["TotalIssuance"]
            )
            + diff
        )

        self.chain_state["System"]["Account"][ss58_address] = {
            "data": {"free": {self.block_number: balance.rao}}
        }

        return True, None

    # Alias for force_set_balance
    sudo_force_set_balance = force_set_balance

    def do_block_step(self) -> None:
        self.block_number += 1

        # Doesn't do epoch
        subtensor_state = self.chain_state["SubtensorModule"]
        for subnet in subtensor_state["NetworksAdded"]:
            subtensor_state["BlocksSinceLastStep"][subnet][self.block_number] = (
                self._get_most_recent_storage(
                    subtensor_state["BlocksSinceLastStep"][subnet]
                )
                + 1
            )

    def _handle_type_default(self, name: str, params: List[object]) -> object:
        defaults_mapping = {
            "TotalStake": 0,
            "TotalHotkeyStake": 0,
            "TotalColdkeyStake": 0,
            "Stake": 0,
        }

        return defaults_mapping.get(name, None)

    def query_subtensor(
        self,
        name: str,
        block: Optional[int] = None,
        params: Optional[List[object]] = [],
    ) -> MockSubtensorValue:
        if block:
            if self.block_number < block:
                raise Exception("Cannot query block in the future")

        else:
            block = self.block_number

        state = self.chain_state["SubtensorModule"][name]
        if state is not None:
            # Use prefix
            if len(params) > 0:
                while state is not None and len(params) > 0:
                    state = state.get(params.pop(0), None)
                    if state is None:
                        return SimpleNamespace(
                            value=self._handle_type_default(name, params)
                        )

            # Use block
            state_at_block = state.get(block, None)
            while state_at_block is None and block > 0:
                block -= 1
                state_at_block = self.state.get(block, None)
            if state_at_block is not None:
                return SimpleNamespace(value=state_at_block)

            return SimpleNamespace(value=self._handle_type_default(name, params))
        else:
            return SimpleNamespace(value=self._handle_type_default(name, params))

    def query_map_subtensor(
        self,
        name: str,
        block: Optional[int] = None,
        params: Optional[List[object]] = [],
    ) -> Optional[MockMapResult]:
        """
        Note: Double map requires one param
        """
        if block:
            if self.block_number < block:
                raise Exception("Cannot query block in the future")

        else:
            block = self.block_number

        state = self.chain_state["SubtensorModule"][name]
        if state is not None:
            # Use prefix
            if len(params) > 0:
                while state is not None and len(params) > 0:
                    state = state.get(params.pop(0), None)
                    if state is None:
                        return MockMapResult([])

            # Check if single map or double map
            if len(state.keys()) == 0:
                return MockMapResult([])

            inner = list(state.values())[0]
            # Should have at least one key
            if len(inner.keys()) == 0:
                raise Exception("Invalid state")

            # Check if double map
            if isinstance(list(inner.values())[0], dict):
                # is double map
                raise ChainQueryError("Double map requires one param")

            # Iterate over each key and add value to list, max at block
            records = []
            for key in state:
                result = self._get_most_recent_storage(state[key], block)
                if result is None:
                    continue  # Skip if no result for this key at `block` or earlier

                records.append((key, result))

            return MockMapResult(records)
        else:
            return MockMapResult([])

    def query_constant(
        self, module_name: str, constant_name: str, block: Optional[int] = None
    ) -> Optional[object]:
        if block:
            if self.block_number < block:
                raise Exception("Cannot query block in the future")

        else:
            block = self.block_number

        state = self.chain_state.get(module_name, None)
        if state is not None:
            if constant_name in state:
                state = state[constant_name]
            else:
                return None

            # Use block
            state_at_block = self._get_most_recent_storage(state, block)
            if state_at_block is not None:
                return SimpleNamespace(value=state_at_block)

            return state_at_block["data"]["free"]  # Can be None
        else:
            return None

    def get_current_block(self) -> int:
        return self.block_number

    # ==== Balance RPC methods ====

    def get_balance(self, address: str, block: int = None) -> "Balance":
        if block:
            if self.block_number < block:
                raise Exception("Cannot query block in the future")

        else:
            block = self.block_number

        state = self.chain_state["System"]["Account"]
        if state is not None:
            if address in state:
                state = state[address]
            else:
                return Balance(0)

            # Use block
            balance_state = state["data"]["free"]
            state_at_block = self._get_most_recent_storage(
                balance_state, block
            )  # Can be None
            if state_at_block is not None:
                bal_as_int = state_at_block
                return Balance.from_rao(bal_as_int)
            else:
                return Balance(0)
        else:
            return Balance(0)

    def get_balances(self, block: int = None) -> Dict[str, "Balance"]:
        balances = {}
        for address in self.chain_state["System"]["Account"]:
            balances[address] = self.get_balance(address, block)

        return balances

    # ==== Neuron RPC methods ====

    def neuron_for_uid(
        self, uid: int, netuid: int, block: Optional[int] = None
    ) -> Optional[NeuronInfo]:
        if uid is None:
            return NeuronInfo._null_neuron()

        if block:
            if self.block_number < block:
                raise Exception("Cannot query block in the future")

        else:
            block = self.block_number

        if netuid not in self.chain_state["SubtensorModule"]["NetworksAdded"]:
            return None

        neuron_info = self._neuron_subnet_exists(uid, netuid, block)
        if neuron_info is None:
            return None

        else:
            return neuron_info

    def neurons(self, netuid: int, block: Optional[int] = None) -> List[NeuronInfo]:
        if netuid not in self.chain_state["SubtensorModule"]["NetworksAdded"]:
            raise Exception("Subnet does not exist")

        neurons = []
        subnet_n = self._get_most_recent_storage(
            self.chain_state["SubtensorModule"]["SubnetworkN"][netuid], block
        )
        for uid in range(subnet_n):
            neuron_info = self.neuron_for_uid(uid, netuid, block)
            if neuron_info is not None:
                neurons.append(neuron_info)

        return neurons

    @staticmethod
    def _get_most_recent_storage(
        storage: Dict[BlockNumber, Any], block_number: Optional[int] = None
    ) -> Any:
        if block_number is None:
            items = list(storage.items())
            items.sort(key=lambda x: x[0], reverse=True)
            if len(items) == 0:
                return None

            return items[0][1]

        else:
            while block_number >= 0:
                if block_number in storage:
                    return storage[block_number]

                block_number -= 1

            return None

    def _get_axon_info(
        self, netuid: int, hotkey: str, block: Optional[int] = None
    ) -> AxonInfoDict:
        # Axons [netuid][hotkey][block_number]
        subtensor_state = self.chain_state["SubtensorModule"]
        if netuid not in subtensor_state["Axons"]:
            return AxonInfoDict.default()

        if hotkey not in subtensor_state["Axons"][netuid]:
            return AxonInfoDict.default()

        result = self._get_most_recent_storage(
            subtensor_state["Axons"][netuid][hotkey], block
        )
        if not result:
            return AxonInfoDict.default()

        return result

    def _get_prometheus_info(
        self, netuid: int, hotkey: str, block: Optional[int] = None
    ) -> PrometheusInfoDict:
        subtensor_state = self.chain_state["SubtensorModule"]
        if netuid not in subtensor_state["Prometheus"]:
            return PrometheusInfoDict.default()

        if hotkey not in subtensor_state["Prometheus"][netuid]:
            return PrometheusInfoDict.default()

        result = self._get_most_recent_storage(
            subtensor_state["Prometheus"][netuid][hotkey], block
        )
        if not result:
            return PrometheusInfoDict.default()

        return result

    def _neuron_subnet_exists(
        self, uid: int, netuid: int, block: Optional[int] = None
    ) -> Optional[NeuronInfo]:
        subtensor_state = self.chain_state["SubtensorModule"]
        if netuid not in subtensor_state["NetworksAdded"]:
            return None

        if self._get_most_recent_storage(subtensor_state["SubnetworkN"][netuid]) <= uid:
            return None

        hotkey = self._get_most_recent_storage(subtensor_state["Keys"][netuid][uid])
        if hotkey is None:
            return None

        axon_info_ = self._get_axon_info(netuid, hotkey, block)

        prometheus_info = self._get_prometheus_info(netuid, hotkey, block)

        coldkey = self._get_most_recent_storage(subtensor_state["Owner"][hotkey], block)
        active = self._get_most_recent_storage(
            subtensor_state["Active"][netuid][uid], block
        )
        rank = self._get_most_recent_storage(
            subtensor_state["Rank"][netuid][uid], block
        )
        emission = self._get_most_recent_storage(
            subtensor_state["Emission"][netuid][uid], block
        )
        incentive = self._get_most_recent_storage(
            subtensor_state["Incentive"][netuid][uid], block
        )
        consensus = self._get_most_recent_storage(
            subtensor_state["Consensus"][netuid][uid], block
        )
        trust = self._get_most_recent_storage(
            subtensor_state["Trust"][netuid][uid], block
        )
        validator_trust = self._get_most_recent_storage(
            subtensor_state["ValidatorTrust"][netuid][uid], block
        )
        dividends = self._get_most_recent_storage(
            subtensor_state["Dividends"][netuid][uid], block
        )
        pruning_score = self._get_most_recent_storage(
            subtensor_state["PruningScores"][netuid][uid], block
        )
        last_update = self._get_most_recent_storage(
            subtensor_state["LastUpdate"][netuid][uid], block
        )
        validator_permit = self._get_most_recent_storage(
            subtensor_state["ValidatorPermit"][netuid][uid], block
        )

        weights = self._get_most_recent_storage(
            subtensor_state["Weights"][netuid][uid], block
        )
        bonds = self._get_most_recent_storage(
            subtensor_state["Bonds"][netuid][uid], block
        )

        stake_dict = {
            coldkey: Balance.from_rao(
                self._get_most_recent_storage(
                    subtensor_state["Stake"][hotkey][coldkey], block
                )
            )
            for coldkey in subtensor_state["Stake"][hotkey]
        }

        stake = sum(stake_dict.values())

        weights = [[int(weight[0]), int(weight[1])] for weight in weights]
        bonds = [[int(bond[0]), int(bond[1])] for bond in bonds]
        rank = U16_NORMALIZED_FLOAT(rank)
        emission = emission / RAOPERTAO
        incentive = U16_NORMALIZED_FLOAT(incentive)
        consensus = U16_NORMALIZED_FLOAT(consensus)
        trust = U16_NORMALIZED_FLOAT(trust)
        validator_trust = U16_NORMALIZED_FLOAT(validator_trust)
        dividends = U16_NORMALIZED_FLOAT(dividends)
        prometheus_info = PrometheusInfo.fix_decoded_values(prometheus_info)
        axon_info_ = AxonInfo.from_neuron_info(
            {"hotkey": hotkey, "coldkey": coldkey, "axon_info": axon_info_}
        )

        neuron_info = NeuronInfo(
            hotkey=hotkey,
            coldkey=coldkey,
            uid=uid,
            netuid=netuid,
            active=active,
            rank=rank,
            emission=emission,
            incentive=incentive,
            consensus=consensus,
            trust=trust,
            validator_trust=validator_trust,
            dividends=dividends,
            pruning_score=pruning_score,
            last_update=last_update,
            validator_permit=validator_permit,
            stake=stake,
            stake_dict=stake_dict,
            total_stake=stake,
            prometheus_info=prometheus_info,
            axon_info=axon_info_,
            weights=weights,
            bonds=bonds,
            is_null=False,
        )

        return neuron_info

    def neuron_for_uid_lite(
        self, uid: int, netuid: int, block: Optional[int] = None
    ) -> Optional[NeuronInfoLite]:
        if block:
            if self.block_number < block:
                raise Exception("Cannot query block in the future")

        else:
            block = self.block_number

        if netuid not in self.chain_state["SubtensorModule"]["NetworksAdded"]:
            raise Exception("Subnet does not exist")

        neuron_info = self._neuron_subnet_exists(uid, netuid, block)
        if neuron_info is None:
            return None

        else:
            neuron_info_dict = neuron_info.__dict__
            del neuron_info
            del neuron_info_dict["weights"]
            del neuron_info_dict["bonds"]

            neuron_info_lite = NeuronInfoLite(**neuron_info_dict)
            return neuron_info_lite

    def neurons_lite(
        self, netuid: int, block: Optional[int] = None
    ) -> List[NeuronInfoLite]:
        if netuid not in self.chain_state["SubtensorModule"]["NetworksAdded"]:
            raise Exception("Subnet does not exist")

        neurons = []
        subnet_n = self._get_most_recent_storage(
            self.chain_state["SubtensorModule"]["SubnetworkN"][netuid]
        )
        for uid in range(subnet_n):
            neuron_info = self.neuron_for_uid_lite(uid, netuid, block)
            if neuron_info is not None:
                neurons.append(neuron_info)

        return neurons

    # Extrinsics
    def _do_delegation(
        self,
        wallet: "wallet",
        delegate_ss58: str,
        amount: "Balance",
        wait_for_inclusion: bool = True,
        wait_for_finalization: bool = False,
    ) -> bool:
        # Check if delegate
        if not self.is_hotkey_delegate(hotkey_ss58=delegate_ss58):
            raise Exception("Not a delegate")

        # do stake
        success = self._do_stake(
            wallet=wallet,
            hotkey_ss58=delegate_ss58,
            amount=amount,
            wait_for_inclusion=wait_for_inclusion,
            wait_for_finalization=wait_for_finalization,
        )

        return success

    def _do_undelegation(
        self,
        wallet: "wallet",
        delegate_ss58: str,
        amount: "Balance",
        wait_for_inclusion: bool = True,
        wait_for_finalization: bool = False,
    ) -> bool:
        # Check if delegate
        if not self.is_hotkey_delegate(hotkey_ss58=delegate_ss58):
            raise Exception("Not a delegate")

        # do unstake
        self._do_unstake(
            wallet=wallet,
            hotkey_ss58=delegate_ss58,
            amount=amount,
            wait_for_inclusion=wait_for_inclusion,
            wait_for_finalization=wait_for_finalization,
        )

    def _do_nominate(
        self,
        wallet: "wallet",
        wait_for_inclusion: bool = True,
        wait_for_finalization: bool = False,
    ) -> bool:
        hotkey_ss58 = wallet.hotkey.ss58_address
        coldkey_ss58 = wallet.coldkeypub.ss58_address

        subtensor_state = self.chain_state["SubtensorModule"]
        if self.is_hotkey_delegate(hotkey_ss58=hotkey_ss58):
            return True

        else:
            subtensor_state["Delegates"][hotkey_ss58] = {}
            subtensor_state["Delegates"][hotkey_ss58][
                self.block_number
            ] = 0.18  # Constant for now

            return True

    def get_transfer_fee(
        self, wallet: "wallet", dest: str, value: Union["Balance", float, int]
    ) -> "Balance":
        return Balance(700)

    def _do_transfer(
        self,
        wallet: "wallet",
        dest: str,
        transfer_balance: "Balance",
        wait_for_inclusion: bool = True,
        wait_for_finalization: bool = False,
    ) -> Tuple[bool, Optional[str], Optional[str]]:
        bal = self.get_balance(wallet.coldkeypub.ss58_address)
        dest_bal = self.get_balance(dest)
        transfer_fee = self.get_transfer_fee(wallet, dest, transfer_balance)

        existential_deposit = self.get_existential_deposit()

        if bal < transfer_balance + existential_deposit + transfer_fee:
            raise Exception("Insufficient balance")

        # Remove from the free balance
        self.chain_state["System"]["Account"][wallet.coldkeypub.ss58_address]["data"][
            "free"
        ][self.block_number] = (bal - transfer_balance - transfer_fee).rao

        # Add to the free balance
        if dest not in self.chain_state["System"]["Account"]:
            self.chain_state["System"]["Account"][dest] = {"data": {"free": {}}}

        self.chain_state["System"]["Account"][dest]["data"]["free"][
            self.block_number
        ] = (dest_bal + transfer_balance).rao

        return True, None, None

    def _do_pow_register(
        self,
        netuid: int,
        wallet: "wallet",
        pow_result: "POWSolution",
        wait_for_inclusion: bool = False,
        wait_for_finalization: bool = True,
    ) -> Tuple[bool, Optional[str]]:
        # Assume pow result is valid

        subtensor_state = self.chain_state["SubtensorModule"]
        if netuid not in subtensor_state["NetworksAdded"]:
            raise Exception("Subnet does not exist")

        self._register_neuron(
            netuid=netuid,
            hotkey=wallet.hotkey.ss58_address,
            coldkey=wallet.coldkeypub.ss58_address,
        )

        return True, None

    def _do_burned_register(
        self,
        netuid: int,
        wallet: "wallet",
        wait_for_inclusion: bool = False,
        wait_for_finalization: bool = True,
    ) -> Tuple[bool, Optional[str]]:
        subtensor_state = self.chain_state["SubtensorModule"]
        if netuid not in subtensor_state["NetworksAdded"]:
            raise Exception("Subnet does not exist")

        bal = self.get_balance(wallet.coldkeypub.ss58_address)
        burn = self.burn(netuid=netuid)
        existential_deposit = self.get_existential_deposit()

        if bal < burn + existential_deposit:
            raise Exception("Insufficient funds")

        self._register_neuron(
            netuid=netuid,
            hotkey=wallet.hotkey.ss58_address,
            coldkey=wallet.coldkeypub.ss58_address,
        )

        # Burn the funds
        self.chain_state["System"]["Account"][wallet.coldkeypub.ss58_address]["data"][
            "free"
        ][self.block_number] = (bal - burn).rao

        return True, None

    def _do_stake(
        self,
        wallet: "wallet",
        hotkey_ss58: str,
        amount: "Balance",
        wait_for_inclusion: bool = True,
        wait_for_finalization: bool = False,
    ) -> bool:
        subtensor_state = self.chain_state["SubtensorModule"]

        bal = self.get_balance(wallet.coldkeypub.ss58_address)
        curr_stake = self.get_stake_for_coldkey_and_hotkey(
            hotkey_ss58=hotkey_ss58, coldkey_ss58=wallet.coldkeypub.ss58_address
        )
        if curr_stake is None:
            curr_stake = Balance(0)
        existential_deposit = self.get_existential_deposit()

        if bal < amount + existential_deposit:
            raise Exception("Insufficient funds")

        stake_state = subtensor_state["Stake"]

        # Stake the funds
        if not hotkey_ss58 in stake_state:
            stake_state[hotkey_ss58] = {}
        if not wallet.coldkeypub.ss58_address in stake_state[hotkey_ss58]:
            stake_state[hotkey_ss58][wallet.coldkeypub.ss58_address] = {}

        stake_state[hotkey_ss58][wallet.coldkeypub.ss58_address][
            self.block_number
        ] = amount.rao

        # Add to total_stake storage
        subtensor_state["TotalStake"][self.block_number] = (
            self._get_most_recent_storage(subtensor_state["TotalStake"]) + amount.rao
        )

        total_hotkey_stake_state = subtensor_state["TotalHotkeyStake"]
        if not hotkey_ss58 in total_hotkey_stake_state:
            total_hotkey_stake_state[hotkey_ss58] = {}

        total_coldkey_stake_state = subtensor_state["TotalColdkeyStake"]
        if not wallet.coldkeypub.ss58_address in total_coldkey_stake_state:
            total_coldkey_stake_state[wallet.coldkeypub.ss58_address] = {}

        curr_total_hotkey_stake = self.query_subtensor(
            name="TotalHotkeyStake",
            params=[hotkey_ss58],
            block=min(self.block_number - 1, 0),
        )
        curr_total_coldkey_stake = self.query_subtensor(
            name="TotalColdkeyStake",
            params=[wallet.coldkeypub.ss58_address],
            block=min(self.block_number - 1, 0),
        )

        total_hotkey_stake_state[hotkey_ss58][self.block_number] = (
            curr_total_hotkey_stake.value + amount.rao
        )
        total_coldkey_stake_state[wallet.coldkeypub.ss58_address][self.block_number] = (
            curr_total_coldkey_stake.value + amount.rao
        )

        # Remove from free balance
        self.chain_state["System"]["Account"][wallet.coldkeypub.ss58_address]["data"][
            "free"
        ][self.block_number] = (bal - amount).rao

        return True

    def _do_unstake(
        self,
        wallet: "wallet",
        hotkey_ss58: str,
        amount: "Balance",
        wait_for_inclusion: bool = True,
        wait_for_finalization: bool = False,
    ) -> bool:
        subtensor_state = self.chain_state["SubtensorModule"]

        bal = self.get_balance(wallet.coldkeypub.ss58_address)
        curr_stake = self.get_stake_for_coldkey_and_hotkey(
            hotkey_ss58=hotkey_ss58, coldkey_ss58=wallet.coldkeypub.ss58_address
        )
        if curr_stake is None:
            curr_stake = Balance(0)

        if curr_stake < amount:
            raise Exception("Insufficient funds")

        stake_state = subtensor_state["Stake"]

        if curr_stake.rao == 0:
            return True

        # Unstake the funds
        # We know that the hotkey has stake, so we can just remove it
        stake_state[hotkey_ss58][wallet.coldkeypub.ss58_address][self.block_number] = (
            curr_stake - amount
        ).rao
        # Add to the free balance
        if wallet.coldkeypub.ss58_address not in self.chain_state["System"]["Account"]:
            self.chain_state["System"]["Account"][wallet.coldkeypub.ss58_address] = {
                "data": {"free": {}}
            }

        # Remove from total stake storage
        subtensor_state["TotalStake"][self.block_number] = (
            self._get_most_recent_storage(subtensor_state["TotalStake"]) - amount.rao
        )

        total_hotkey_stake_state = subtensor_state["TotalHotkeyStake"]
        if not hotkey_ss58 in total_hotkey_stake_state:
            total_hotkey_stake_state[hotkey_ss58] = {}
            total_hotkey_stake_state[hotkey_ss58][
                self.block_number
            ] = 0  # Shouldn't happen

        total_coldkey_stake_state = subtensor_state["TotalColdkeyStake"]
        if not wallet.coldkeypub.ss58_address in total_coldkey_stake_state:
            total_coldkey_stake_state[wallet.coldkeypub.ss58_address] = {}
            total_coldkey_stake_state[wallet.coldkeypub.ss58_address][
                self.block_number
            ] = amount.rao  # Shouldn't happen

        total_hotkey_stake_state[hotkey_ss58][self.block_number] = (
            self._get_most_recent_storage(
                subtensor_state["TotalHotkeyStake"][hotkey_ss58]
            )
            - amount.rao
        )
        total_coldkey_stake_state[wallet.coldkeypub.ss58_address][self.block_number] = (
            self._get_most_recent_storage(
                subtensor_state["TotalColdkeyStake"][wallet.coldkeypub.ss58_address]
            )
            - amount.rao
        )

        self.chain_state["System"]["Account"][wallet.coldkeypub.ss58_address]["data"][
            "free"
        ][self.block_number] = (bal + amount).rao

        return True

    def get_delegate_by_hotkey(
        self, hotkey_ss58: str, block: Optional[int] = None
    ) -> Optional["DelegateInfo"]:
        subtensor_state = self.chain_state["SubtensorModule"]

        if hotkey_ss58 not in subtensor_state["Delegates"]:
            return None

        newest_state = self._get_most_recent_storage(
            subtensor_state["Delegates"][hotkey_ss58], block
        )
        if newest_state is None:
            return None

        nom_result = []
        nominators = subtensor_state["Stake"][hotkey_ss58]
        for nominator in nominators:
            nom_amount = self.get_stake_for_coldkey_and_hotkey(
                hotkey_ss58=hotkey_ss58, coldkey_ss58=nominator, block=block
            )
            if nom_amount is not None and nom_amount.rao > 0:
                nom_result.append((nominator, nom_amount))

        registered_subnets = []
        for subnet in self.get_all_subnet_netuids(block=block):
            uid = self.get_uid_for_hotkey_on_subnet(
                hotkey_ss58=hotkey_ss58, netuid=subnet, block=block
            )

            if uid is not None:
                registered_subnets.append((subnet, uid))

        info = DelegateInfo(
            hotkey_ss58=hotkey_ss58,
            total_stake=self.get_total_stake_for_hotkey(ss58_address=hotkey_ss58)
            or Balance(0),
            nominators=nom_result,
            owner_ss58=self.get_hotkey_owner(hotkey_ss58=hotkey_ss58, block=block),
            take=0.18,
            validator_permits=[
                subnet
                for subnet, uid in registered_subnets
                if self.neuron_has_validator_permit(uid=uid, netuid=subnet, block=block)
            ],
            registrations=[subnet for subnet, _ in registered_subnets],
            return_per_1000=Balance.from_tao(1234567),  # Doesn't matter for mock?
            total_daily_return=Balance.from_tao(1234567),  # Doesn't matter for mock?
        )

        return info

    def get_delegates(self, block: Optional[int] = None) -> List["DelegateInfo"]:
        subtensor_state = self.chain_state["SubtensorModule"]
        delegates_info = []
        for hotkey in subtensor_state["Delegates"]:
            info = self.get_delegate_by_hotkey(hotkey_ss58=hotkey, block=block)
            if info is not None:
                delegates_info.append(info)

        return delegates_info

    def get_delegated(
        self, coldkey_ss58: str, block: Optional[int] = None
    ) -> List[Tuple["DelegateInfo", "Balance"]]:
        """Returns the list of delegates that a given coldkey is staked to."""
        delegates = self.get_delegates(block=block)

        result = []
        for delegate in delegates:
            if coldkey_ss58 in delegate.nominators:
                result.append((delegate, delegate.nominators[coldkey_ss58]))

        return result

    def get_all_subnets_info(self, block: Optional[int] = None) -> List[SubnetInfo]:
        subtensor_state = self.chain_state["SubtensorModule"]
        result = []
        for subnet in subtensor_state["NetworksAdded"]:
            info = self.get_subnet_info(netuid=subnet, block=block)
            if info is not None:
                result.append(info)

        return result

    def get_subnet_info(
        self, netuid: int, block: Optional[int] = None
    ) -> Optional[SubnetInfo]:
        if not self.subnet_exists(netuid=netuid, block=block):
            return None

        def query_subnet_info(name: str) -> Optional[object]:
            return self.query_subtensor(name=name, block=block, params=[netuid]).value

        info = SubnetInfo(
            netuid=netuid,
            rho=query_subnet_info(name="Rho"),
            kappa=query_subnet_info(name="Kappa"),
            difficulty=query_subnet_info(name="Difficulty"),
            immunity_period=query_subnet_info(name="ImmunityPeriod"),
            max_allowed_validators=query_subnet_info(name="MaxAllowedValidators"),
            min_allowed_weights=query_subnet_info(name="MinAllowedWeights"),
            max_weight_limit=query_subnet_info(name="MaxWeightLimit"),
            scaling_law_power=query_subnet_info(name="ScalingLawPower"),
            subnetwork_n=query_subnet_info(name="SubnetworkN"),
            max_n=query_subnet_info(name="MaxAllowedUids"),
            blocks_since_epoch=query_subnet_info(name="BlocksSinceLastStep"),
            tempo=query_subnet_info(name="Tempo"),
            modality=query_subnet_info(name="NetworkModality"),
            connection_requirements={
                str(netuid_.value): percentile.value
                for netuid_, percentile in self.query_map_subtensor(
                    name="NetworkConnect", block=block, params=[netuid]
                ).records
            },
            emission_value=query_subnet_info(name="EmissionValues"),
            burn=query_subnet_info(name="Burn"),
            owner_ss58=query_subnet_info(name="SubnetOwner"),
        )

        return info

    def _do_serve_prometheus(
        self,
        wallet: "wallet",
        call_params: "PrometheusServeCallParams",
        wait_for_inclusion: bool = False,
        wait_for_finalization: bool = True,
    ) -> Tuple[bool, Optional[str]]:
        return True, None

    def _do_set_weights(
        self,
        wallet: "wallet",
        netuid: int,
        uids: int,
        vals: List[int],
        version_key: int,
        wait_for_inclusion: bool = False,
        wait_for_finalization: bool = True,
    ) -> Tuple[bool, Optional[str]]:
        return True, None

    def _do_serve_axon(
        self,
        wallet: "wallet",
        call_params: "AxonServeCallParams",
        wait_for_inclusion: bool = False,
        wait_for_finalization: bool = True,
    ) -> Tuple[bool, Optional[str]]:
        return True, None


import itertools
from collections import deque
import random
import time

def print_output(func):
    def wrapper(*args):
        results = func(*args)
        print(f"output for {func.__name__} :\n{results} ")
        return results
    return wrapper

class Card:

    def __init__(self, rank: int, suit: str):
        self.ranks_representation = (
            None, "Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack",
            "Queen", "King", "Ace"
        )
        self.suit_representation = {
            'D': 'Diamonds', 'S': 'Spades', 'C': 'Clubs', 'H': 'Hearts'
        }
        self.rank = rank
        self.suit = suit

    def return_rank_and_suit(self):
        return self.rank, self.suit

    def __repr__(self):
        return f"{self.ranks_representation[self.rank]} of {self.suit_representation[self.suit]}"

class HandRanker:

    def get_high_card(self, hand):
        card_numbers = tuple(set([card.rank for card in hand]))
        return tuple(sorted(card_numbers))

    def get_pairs(self, hand):
        card_numbers = [card.rank for card in hand]
        number_of_cards_in_a_pair = 2
        pairs = ()
        for card_number in card_numbers:
            if card_numbers.count(card_number) == number_of_cards_in_a_pair:
                pairs += (card_number,)
        if pairs != ():
            return tuple(set(pairs))

    def get_two_pairs(self, hand):
        try:
            if len(set(self.get_pairs(hand))) == 2:
                return set(self.get_pairs(hand))
        except TypeError:  # This excepts where hand is None because no pair
            pass

    def get_three_of_a_kind(self, hand):
        card_numbers = [card.rank for card in hand]
        triples = ()
        for card_number in card_numbers:
            if card_numbers.count(card_number) == 3:
                triples += (card_number,)
        if triples != ():
            return triples

    def get_straight_with_low_ace(self, hand):
        """
        Check if a straight exists if the ace is treated as a low ace.
        Hand is an iterable of Card instances.
        """
        low_ace_n = 1
        high_ace_n = 14
        card_numbers = set([card.rank for card in hand])
        card_numbers = [low_ace_n if n == high_ace_n else n for n in card_numbers]
        card_numbers.sort()
        high_card, low_card = card_numbers[-1], card_numbers[0]
        if len(card_numbers) == 5 and high_card - low_card == 4:
            return tuple(card_numbers)

    def get_straight_without_low_ace(self, hand):
        card_numbers = list(set(sorted([card.rank for card in hand])))
        high_card, low_card = card_numbers[-1], card_numbers[0]
        if len(card_numbers) == 5 and high_card - low_card == 4:
            return tuple(card_numbers)

    def get_straights(self, hand):
        straight_functions = (
            self.get_straight_with_low_ace,
            self.get_straight_without_low_ace
        )
        for f in straight_functions:
            if f(hand):
                return f(hand)

    def get_flush(self, hand):
        card_suites = tuple([card.suit for card in hand])
        card_numbers = [card.rank for card in hand]
        if len(card_numbers) == 5 and len(set(card_suites)) == 1:
            return card_suites[1]

    def get_full_house(self, hand):
        card_numbers = tuple([card.rank for card in hand])
        if self.get_three_of_a_kind(hand) is not None:
            if self.get_pairs(hand):
                return tuple(card_numbers)

    def get_four_of_a_kind(self, hand):
        card_numbers = [card.rank for card in hand]
        quads = ()
        for card_number in card_numbers:
            if card_numbers.count(card_number) == 4:
                quads += (card_number,)
        if quads != ():
            return quads

    def get_straight_flush(self, hand):
        if self.get_straights(hand) and self.get_flush(hand):
            return sorted(hand, key=lambda n: n.rank)

    hand_ranks = {
        get_straight_flush: 9,
        get_four_of_a_kind: 8,
        get_full_house: 7,
        get_flush: 6,
        get_straights: 5,
        get_three_of_a_kind: 4,
        get_two_pairs: 3,
        get_pairs: 2,
        get_high_card: 1
    }

    def rank_hand(self, hand: list) -> int:
        for f, rank in self.hand_ranks.items():
            if f(self, hand):
                return rank
        return -1

    def rank_hands(self, hands):
        """Get each hand and assign it a rank."""
        ranked_hands = []
        for hand in hands:
            rank = self.rank_hand(sorted(hand, key=lambda n: n.rank))
            ranked_hands.append((rank, hand))
        return ranked_hands

class HandClassifier(HandRanker):

    def filter_hands_by_highest_score(self, hands: list) -> list:
        high_score = self.get_highest_hand_score(hands)
        return [
            hand for hand in hands
            if self.rank_hand(hand) == high_score
        ]

    def get_highest_hand_score(self, hands) -> int:
        highest_hand_score = 0
        for hand in hands:
            if self.rank_hand(hand) >= highest_hand_score:
                highest_hand_score = self.rank_hand(hand)
        return highest_hand_score

    def get_winning_hands_from(self, raw_hands):
        hands_with_highest_score = self.filter_hands_by_highest_score(
            raw_hands
        )
        best_hand = self.get_hand_with_highest_card_rank(
            hands_with_highest_score
        )
        all_best_hands = [
            hand for hand in hands_with_highest_score
            if self.are_equal(
                self.get_card_ranks(best_hand),
                self.get_card_ranks(hand)
            )
        ]
        return all_best_hands

    def get_hand_with_highest_card_rank(self, filtered_hands: list) -> list:
        current_best_hand = filtered_hands[0]
        highest_ranks = self.get_card_ranks(filtered_hands[0])
        for hand in filtered_hands:
            challenger_ranks = self.get_card_ranks(hand)
            if self.is_higher(highest_ranks, challenger_ranks):
                current_best_hand = hand
                highest_ranks = challenger_ranks
        return current_best_hand

    def get_card_ranks(self, hand: list) -> list:
        return self.sort_by_frequency_and_size([card.rank for card in hand])

    @staticmethod
    def is_higher(current_n: list, challenger_n: list) -> bool:
        for a, b in zip(current_n, challenger_n):
            if a > b:
                return False
            if b > a:
                return True
        return False

    @staticmethod
    def are_equal(current_n: list, challenger_n: list) -> bool:
        for a, b in zip(current_n, challenger_n):
            if a > b:
                return False
            if b > a:
                return False
        return True

    @staticmethod
    def sort_by_frequency_and_size(numbers):
        """Sort by descending frequency and descending size."""
        numbers.sort(reverse=True)
        numbers = sorted(
            numbers, key=lambda n: numbers.count(n), reverse=True
        )
        return numbers

class Hand(HandClassifier):

    def __init__(self):
        self.pocket_cards = []
        self.hand_cards = []

    def generate_hand_combinations(self, card_dealer) -> list:
        card_pool = self.pocket_cards + card_dealer.table_cards
        return list(itertools.combinations(card_pool, r=5))

    def calculate_best_hand_for_player(self, card_dealer) -> list:
        if not card_dealer.table_cards:
            self.hand_cards = self.pocket_cards
            return self.hand_cards
        else:
            combinations: list = self.generate_hand_combinations(card_dealer)
            filtered = self.filter_hands_by_highest_score(combinations)
            self.hand_cards = self.get_hand_with_highest_card_rank(filtered)
            return self.hand_cards

    def print_best_hand(self):
        print(self.hand_cards)

    def reset_for_new_round(self):
        self.pocket_cards = []
        self.hand_cards = []

class Player:
    def __init__(self, name):
        self.name = name
        self.hand = Hand()
        self.money = 1000
        self.amount_bet_during_stage = 0
        self.amount_bet_during_round = 0
        self.has_folded = False
        self.has_acted_during_stage = False
        self.in_big_blind_position = False
        self.in_small_blind_position = False
        self.in_dealer_position = False
        self.is_all_in = False
        self.max_winnings = 0

    def get_best_hand(self, card_dealer):
        return self.hand.calculate_best_hand_for_player(card_dealer)

    def __repr__(self):
        return f"{self.name} instance"

    def print_pocket_cards(self):
        print(f"pocket cards -> {self.hand.pocket_cards}")

    def print_status(self):
        print("----")
        print(f"{self.name.title()},\n" +
              f"You have {self.money} coins currently.\n" +
              f"You have bet {self.amount_bet_during_stage} " +
              f"this stage.\n"
              )

    def reset_for_new_round(self):
        self.hand.reset_for_new_round()
        self.amount_bet_during_stage = 0
        self.amount_bet_during_round = 0
        self.has_folded = False
        self.has_acted_during_stage = False
        self.in_big_blind_position = False
        self.in_small_blind_position = False
        self.in_dealer_position = False
        self.is_all_in = False
        self.max_winnings = 0

class Players:
    """
    Use .register to access the different players in Players.
    """

    def __init__(self, number_of_players):
        self.number_of_players = number_of_players
        self.instantiate_all_players()
        self.register = self.store_players_in_register()
        self.playing_order = deque(
            player for player in self.register
        )
        self.highest_stage_bet = 0
        self.pot = 0
        self.small_blind = 20
        self.big_blind = 40
        self.assign_big_blind_player()
        self.assign_small_blind_player()
        self.hand_classifier = HandClassifier()
        self.winning_players = []
        try:
            self.dealer_player = self.playing_order[-3]
        except IndexError:  # Applies where there are only two players
            self.dealer_player = self.playing_order[-1]

    def reset_for_new_round(self):
        self.rotate_playing_order()
        self.highest_stage_bet = 0
        self.pot = 0
        self.assign_big_blind_player()
        self.assign_small_blind_player()
        self.winning_players = []

    def rotate_playing_order(self):
        self.playing_order.rotate(1)

    def instantiate_all_players(self):
        for i in range(1, self.number_of_players + 1):
            setattr(self, f'player{i}', Player(f'player{i}'))

    def store_players_in_register(self):
        return [
            value for value in self.__dict__.values()
            if type(value) == Player
        ]

    def assign_small_blind_player(self):
        """
        The small blind is second-last pre-flop and first post-flop.
        """
        self.small_blind_player: Player = self.playing_order[-2]
        self.small_blind_player.in_small_blind_position = True

    def assign_big_blind_player(self):
        """
        The big blind is last to act pre-flop and second to act post flop.
        """
        self.big_blind_player: Player = self.playing_order[-1]
        self.big_blind_player.in_big_blind_position = True

    def rotate_playing_order_before_flop(self):
        """
        Rotates playing order by 2 to begin from the left of the
        dealer player.
        """
        self.playing_order.rotate(2)

    def pay_blinds(self):
        self.__pay_small_blind()
        self.__pay_big_blind()
        self.pot += self.big_blind + self.small_blind
        self.highest_stage_bet = self.big_blind
        self.print_blinds_message()

    def __pay_small_blind(self):
        self.small_blind_player.money -= self.small_blind
        self.small_blind_player.amount_bet_during_stage += self.small_blind

    def __pay_big_blind(self):
        self.big_blind_player.money -= self.big_blind
        self.big_blind_player.amount_bet_during_stage += self.big_blind

    def print_blinds_message(self):
        print(
            f"The big blind player, {self.big_blind_player.name.title()}, "
            f"paid the big blind of {self.big_blind}.\n" +
            f"The small blind player, {self.small_blind_player.name.title()}, "
            f"paid the small blind of {self.small_blind}.\n"
        )

    def reset_players_status_at_stage_end(self):
        for player_at_stage_end in self.playing_order:
            player_at_stage_end.amount_bet_during_stage = 0
            player_at_stage_end.has_acted_during_stage = False

    def reset_highest_stage_bet(self):
        self.highest_stage_bet = 0

    def get_any_player_that_is_all_in(self):
        for player in self.register:
            if player.money == 0:
                player.is_all_in = True
                yield player

    def set_max_winnings_for_all_in_players(self):
        """Run at each stage's end."""
        for all_in_player in self.get_any_player_that_is_all_in():
            self.set_max_winnings_for_player(all_in_player)

    def set_max_winnings_for_player(self, all_in_player):
        """Creates an max winnings attribute for an all_in player.
        :type all_in_player: Player
        """
        for other_player in self.register:
            if (other_player.amount_bet_during_round >= all_in_player.amount_bet_during_round):
                all_in_player.max_winnings += all_in_player.amount_bet_during_round
            else:
                all_in_player.max_winnings += other_player.amount_bet_during_round

    def ask_all_players_for_actions(self):
        while self.at_least_one_player_must_act():
            for player in self.playing_order:
                if not self.at_least_two_players_left_in_round():
                    return
                if self.has_remaining_actions(player):
                    self.get_player_command(player)
                    self.mark_player_as_having_made_action(player)

    def is_there_any_default_winner(self):
        if not self.at_least_two_players_left_in_round():
            return True

    def set_any_default_winner(self):
        assert self.at_least_two_players_left_in_round() is False
        self.winning_players = self.get_each_not_folded_player()

    def at_least_two_players_left_in_round(self) -> bool:
        if len(self.get_each_not_folded_player()) < 2:
            return False
        else:
            return True

    def get_any_showdown_winner(self, card_dealer) -> list:
        return self.set_winning_players_based_on_winning_hands(card_dealer)

    def get_each_not_folded_player(self) -> list:
        return [
            player for player in self.playing_order
            if player.has_folded is False
        ]

    def set_winning_players_based_on_winning_hands(self, card_dealer) -> list:
        active_players = self.get_each_not_folded_player()
        players_best_hands = [
            active_player.get_best_hand(card_dealer)
            for active_player in active_players
        ]
        self.winning_players = [
            active_player
            for active_player in active_players
            if active_player.get_best_hand(card_dealer)
            in self.hand_classifier.get_winning_hands_from(players_best_hands)
        ]
        return self.winning_players

    def give_pot_to_winners(self):
        for winning_player in self.winning_players:
            winning_player.money += self.calculate_winnings_for(winning_player)

    def calculate_winnings_for(self, winning_player: Player):
        winnings = self.pot // len(self.winning_players)
        if winning_player.max_winnings != 0:
            if winnings > winning_player.max_winnings:
                return winning_player.max_winnings
        return winnings

    def print_winning_players(self):
        if len(self.winning_players) == 1:
            print(f"The winning player is {self.winning_players[0].name.title()}")
            print(f"{self.winning_players[0].name.title()} won {self.pot}.")
        else:
            print("The winning players are ")
            for counter, winning_player in enumerate(self.winning_players):
                print(f"{winning_player.name}, ")
                if counter == len(self.winning_players) - 1:
                    print("and")

    def has_remaining_actions(self, player: Player) -> bool:
        if player.has_folded or player.is_all_in is True:
            return False
        if player.has_acted_during_stage and (
                player.amount_bet_during_stage == self.highest_stage_bet
        ):
            return False
        else:
            return True

    def at_least_one_player_must_act(self) -> bool:
        for player in self.register:
            if self.has_remaining_actions(player) is True:
                return True
        return False

    def get_player_command(self, player):
        command = self.get_command(player)
        if self.input_is_valid(command):
            if self.execute_command(command, player) is False:  # I don't like this. What is a good way to improve this?
                self.get_player_command(player)
        else:
            self.print_command_is_invalid()
            self.get_player_command(player)

    def get_command(self, player):
        player.print_status()
        player.print_pocket_cards()
        try:
            command = int(
                input(
                    "Would you like to check (0), call (1), raise (2), " +
                    "or fold (3)? Enter command >>\n\n")
            )

        except ValueError:
            self.print_command_is_invalid()
            return self.get_command(player)
        return command

    def print_command_is_invalid(self):
        print("Your command is invalid.\n")

    @staticmethod
    def input_is_valid(command) -> bool:
        if command not in [0, 1, 2, 3]:
            return False
        return True

    def execute_command(self, command, active_player) -> bool:
        player_options = {
            0: self.check_bet,
            1: self.call_bet,
            2: self.raise_bet,
            3: self.fold_hand
        }
        return player_options[command](active_player)

    def call_bet(self, calling_player: Player) -> bool:
        """This will make the player check if there is no higher bet."""
        call_amount = (
                self.highest_stage_bet -
                calling_player.amount_bet_during_stage
        )
        if calling_player.money - call_amount > 0:
            calling_player.amount_bet_during_stage += call_amount
            calling_player.amount_bet_during_round += call_amount
            self.pot += call_amount
            calling_player.money -= call_amount
            print(
                f"{calling_player.name.title()} called {call_amount}."
            )
        else:
            calling_player.amount_bet_during_stage += calling_player.money
            calling_player.amount_bet_during_round += calling_player.money
            self.pot += calling_player.money
            calling_player.money = 0
            print(
                f"{calling_player.name.title()} "
                f"calls by going all in"
            )

    @staticmethod
    def fold_hand(folding_player):
        folding_player.has_folded = True
        print(f"{folding_player.name.title()} folded.")

    def raise_bet(self, player) -> bool:
        proposed_bet_amount = self.get_amount_to_raise(player)
        if self.is_bet_valid(player, proposed_bet_amount):
            self.place_bet(player, proposed_bet_amount)
            return True
        else:
            return False

    def get_amount_to_raise(self, raising_player):
        bet_amount = int(
            input(
                f"Enter the amount to raise above {self.highest_stage_bet}\n"
                f"(The highest bet during this stage is {self.highest_stage_bet})"
                f" >>\n"
            )
        )
        bet_amount += self.highest_stage_bet - raising_player.amount_bet_during_stage
        return bet_amount

    @staticmethod
    def is_bet_valid(raising_player, bet_amount):
        if raising_player.money - bet_amount < 0:
            print(
                f"Invalid bet. " +
                f"{raising_player.name.title()} does not have enough money."
            )
            return False
        return True

    def place_bet(self, raising_player: Player, bet_amount):
        raising_player.money -= bet_amount
        raising_player.amount_bet_during_stage += bet_amount
        raising_player.amount_bet_during_round += bet_amount
        self.highest_stage_bet = raising_player.amount_bet_during_stage
        self.pot += bet_amount
        print(f"{raising_player.name.title()} bet {bet_amount}.")

    def check_bet(self, checking_player: Player) -> bool:
        if checking_player.amount_bet_during_stage == self.highest_stage_bet:
            return True
        else:
            print(
                f"Invalid action. {checking_player.name.title()} " +
                "must match the highest current bet of " +
                f"{self.highest_stage_bet} to check"
            )
            return False

    @staticmethod
    def mark_player_as_having_made_action(player_who_made_action: Player):
        player_who_made_action.has_acted_during_stage = True

    def print_players_money(self):
        print("Player money:")
        for player in self.register:
            print(f"{player.name} has £{player.money}")

class CardDealer:
    def __init__(self):
        self.table_cards = []
        self.deck = self.generate_cards()

    @staticmethod
    def generate_cards():
        card_templates = itertools.product(range(2, 15), ('H', 'D', 'S', 'C'))
        return [Card(rank, suit) for rank, suit in card_templates]

    def pick_card(self) -> Card:
        random.shuffle(self.deck)
        return self.deck.pop()

    def deal_pocket_cards_to_player(self, receiving_player: Player) -> None:
        for i in range(2):
            picked_card = self.pick_card()
            receiving_player.hand.pocket_cards.append(picked_card)

    def deal_pocket_cards_to_players(self, receiving_players: Players) -> None:
        for receiving_player in receiving_players.register:
            self.deal_pocket_cards_to_player(receiving_player)

    def __deal_card_to_table(self):
        card = self.pick_card()
        self.table_cards.append(card)

    def deal_flop(self):
        for i in range(3):
            self.__deal_card_to_table()

    def deal_turn(self):
        self.__deal_card_to_table()

    def deal_river(self):
        self.__deal_card_to_table()

    def show_table(self):
        print("______________________\n")
        print(f"Table cards : \n{self.table_cards}")
        print("______________________\n")

    def reset_for_new_round(self):
        self.table_cards = []

class Game:
    def __init__(self, number_of_players):
        self.n_players = number_of_players
        self.all_players = Players(self.n_players)
        self.card_dealer = CardDealer()
        self.hand_classifier = HandClassifier()

    def play_game(self):
        self.play_round()
        self.run_post_round_events()

    def play_round(self):
        if self.run_pre_flop_events() == "end round":
            return
        if self.run_flop_events() == "end round":
            return
        if self.run_turn_events() == "end round":
            return
        self.run_river_events()

    def execute_round_events(self):
        self.all_players.ask_all_players_for_actions()
        if self.all_players.is_there_any_default_winner() is True:
            self.all_players.set_any_default_winner()
            self.all_players.print_winning_players()
            self.all_players.give_pot_to_winners()
            return "end round"
        self.all_players.reset_players_status_at_stage_end()
        self.all_players.reset_highest_stage_bet()

    def run_pre_flop_events(self):
        self.card_dealer.deal_pocket_cards_to_players(self.all_players)
        self.all_players.pay_blinds()
        if self.execute_round_events() == "end round":
            return "end round"
        self.all_players.rotate_playing_order_before_flop()

    def run_flop_events(self):
        self.card_dealer.deal_flop()
        self.card_dealer.show_table()
        if self.execute_round_events() == "end round":
            return "end round"

    def run_turn_events(self):
        self.card_dealer.deal_turn()
        self.card_dealer.show_table()
        if self.execute_round_events():
            return "end round"

    def run_river_events(self):
        self.card_dealer.deal_river()
        self.card_dealer.show_table()
        if self.execute_round_events() == "end round":
            return "end round"
        self.all_players.get_any_showdown_winner(self.card_dealer)
        self.all_players.print_winning_players()
        self.all_players.give_pot_to_winners()

    def run_post_round_events(self):
        self.all_players.print_players_money()
        if self.do_you_want_to_play_another_round() is True:
            self.prepare_new_round()
            self.play_game()
        else:
            print("Game finished.")
            self.all_players.print_players_money()

    def prepare_new_round(self):
        print("Preparing for new round")
        self.all_players.reset_for_new_round()
        self.card_dealer.reset_for_new_round()

    @staticmethod
    def do_you_want_to_play_another_round():
        seconds = 5
        while time.sleep(seconds):
            print(seconds)
            if input("Press x to end the game").upper() == 'X':
                return False
            seconds -= 1
        return True

if __name__ == "__main__":
    Game(3).play_game()


from collections import Counter
import argparse

import nltk
from nltk.util import ngrams

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('path')
    args = parser.parse_args()

    unique_grams = Counter()

    with open(args.path) as f:
        for line in f.readlines():
            line = line.strip()
            words = nltk.word_tokenize(line)
            grams = ngrams(words, n=3)
            unique_grams.update(grams)

    print('Unique ngrams', len(unique_grams))
    print('Total ngrams', sum(unique_grams.values()))

if __name__ == '__main__':
    main()


import pyupbit
import numpy as np
import time
import datetime

def get_balances(upbit, ticker, value):
    # 종목별 세부항목 조회
    balances = upbit.get_balances()
    for b in balances:
        if b['currency'] == ticker:
            if b[value] is not None:
                return float(b[value])
            else:
                return 0
    return 0

def get_asset(upbit):
    # 총 자산 조회 (현금+평가금액)
    balances = upbit.get_balances() # API 1회 호출
    asset_krw = float(balances[0]['balance'])

    if len(balances) == 1:
        return asset_krw

    else:
        currency = []
        balance = []
        for b in balances:
            if b['currency'] != 'KRW':
                currency.append('KRW-'+b['currency'])
                balance.append(b['balance'])

        current_price = pyupbit.get_current_price(currency)  # API 1회 호출
        if len(currency) == 1:
            current_price = {currency[0]: current_price}

        asset_coin = np.dot(list(map(float, balance)), list(map(float, current_price.values())))

        return asset_krw+asset_coin

def get_ma15(ticker):
    # 15일 이동 평균선 조회
    df = pyupbit.get_ohlcv(ticker, interval="day", count=15)
    ma15 = df['close'].rolling(15).mean().iloc[-1]
    return ma15


import requests

from decouple import config

SMR_URL = config("sourcemaps_reader")

if '%s' in SMR_URL:
    if config("SMR_KEY", default=None) is not None:
        SMR_URL = SMR_URL % config("SMR_KEY")
    else:
        SMR_URL = SMR_URL % "smr"

def get_original_trace(key, positions, is_url=False):
    payload = {
        "key": key,
        "positions": positions,
        "padding": 5,
        "bucket": config('sourcemaps_bucket'),
        "isURL": is_url
    }
    try:
        r = requests.post(SMR_URL, json=payload, timeout=config("sourcemapTimeout", cast=int, default=5))
        if r.status_code != 200:
            print(f"Issue getting sourcemap status_code:{r.status_code}")
            return None
        return r.json()
    except requests.exceptions.Timeout:
        print("Timeout getting sourcemap")
        return None
    except Exception as e:
        print("Issue getting sourcemap")
        print(e)
        return None


class Solution:
    def convert(self, s: str, numRows: int) -> str:
        split_result = ['' for _ in range(numRows)]

        direction = 1
        mark = [0]
        for i in range(1, 2*numRows-2):
            mark.append(mark[i-1] + direction)
            if mark[-1] == numRows - 1:
                direction = -1

        for index in range(len(s)):
            try:
                remain = index % (2*numRows-2)
            except ZeroDivisionError:
                remain = 0
            split_result[mark[remain]] += s[index]

        result = ''
        for i in range(numRows):
            result += split_result[i]

        return result


def order(graph):
    graph = set(graph)
    ordering = []
    possibilities = list({edge[0] for edge in graph} - {edge[1] for edge in graph})

    while len(possibilities) != 0:
        ordering.append(possibilities[0])

        temp_nodes = []
        for edge in filter(lambda e: e[0] == possibilities[0], graph):
            graph.remove(edge)
            temp_nodes.append(edge[1])

        for node in temp_nodes:
            if node not in {edge[1] for edge in graph}:
                possibilities.append(node)

        possibilities = possibilities[1:]

    return ordering

def longest_path(graph, edges, source, sink):
    top_order = order(graph.keys())
    top_order = top_order[top_order.index(source) + 1:top_order.index(sink) + 1]

    S = {node: -100 for node in {edge[0] for edge in graph.keys()} | {edge[1] for edge in graph.keys()}}
    S[source] = 0
    backtrack = {node: None for node in top_order}

    for node in top_order:
        try:
            S[node], backtrack[node] = max(
                map(lambda e: [S[e[0]] + graph[e], e[0]], filter(lambda e: e[1] == node, graph.keys())),
                key=lambda p: p[0])
        except ValueError:
            pass

    path = [sink]
    while path[0] != source:
        path = [backtrack[path[0]]] + path

    return S[sink], path