实用模块:日志记录器、监控器、限制器

0 点赞
编程农场
转载

在本指南中,我想分享一些能为你生活提供便利的模块。其中包括: 日志记录器 资源监控器 时间和资源限制 实用功能与常量集 额外福利! 引言 本指南不包含现成的解决方案或算法! 这是一个实用模块的集合,能够简化你的开发流程并助力调试工作。这些模块包括: 基础日志器 资源监控器 资源、时间及自定义参数限制器 实用函数与常量集 小惊喜 :) 日志器 模块介绍 基础日志器包含3个日志级别: 信息 警告 错误 还支持将日志按部分划分。功能 名称 参数 说明 section name - 段落名称 显示带有新段落名称的分隔符 info msg - 日志文本 显示包含当前时间(秒)的信息消息 warning msg - 日志文本 显示包含当前时间(秒)的警告消息 error msg - 日志文本 显示包含当前时间(秒)的错误消息 使用示例 在新窗口中插入以下代码: import logger logger.section("New section") logger.此代码将输出: === 新章节 === [408.56] [信息] 信息日志 [408.56] [警告] 警告日志 [408.57] [错误] 错误日志 在游戏中的显示效果:

模块代码 请将此代码插入名为logger的窗口: # Logger by ksm # 此模块包含一组可在您的代码中使用的实用函数和常量。监控 关于模块 通过此模块可以创建“标记”,这些标记会记录当前每种资源的数量。之后可以从标记中获取此信息,或者计算两个任意标记之间时间段内的资源获取和消耗速度。 功能 名称 参数 描述 add_marker - 创建新标记并返回其标识符(标记列表中的索引)。新标记会添加到列表末尾。get_marker_info marker - 标记标识符 返回标记信息:创建时间(秒) 字典,其中键为Item类型对象,值为创建标记时该资源的数量 calc_item_rate item - Item类型对象 start_marker - 起始标记标识符(默认第一个) end_marker - 结束标记标识符(默认最后一个) 计算指定标记之间的资源收集或消耗速度。返回:每秒资源速度 资源数量变化 间隔持续时间(秒) log_item_rate 物品 - Item类型对象 起始标记 - 起始标记标识符(默认 - 第一个) 结束标记 - 结束标记标识符(默认 - 最后一个) 输出:资源速度 数量变化 已过去的秒数 输出通过上一节中描述的记录器进行。使用示例 在新窗口中插入以下代码: import monitoring # 准备 set_world_size(3) monitoring.add_marker() # 持续15秒收集干草 start_time = get_time() while get_time() - start_time < 5: for _ in range(3): harvest() move(North) move(East) # 输出统计数据 monitoring.add_marker() monitoring.log_item_rate(Items.Hay) monitoring.log_item_rate(Items.Power) 在我的案例中,此代码输出: [3349.73] [INFO] 在5.09秒内获得30720个Items.Hay(速率:6030.6/秒) [3349.78] [INFO] 在5.09秒内获得-5.13个Items.Power(速率:-1.01/秒) 从日志中可以看出,收集了30720份干草(6030.每秒6个),5秒内消耗5.13能量(每秒1.01)。 游戏内显示如下:

Код модуля Вставьте этот код в окно с именем monitoring: # Monitoring by ksm (https://steamcommunity.com/id/ksm2004/) # This module allows you to easily calculate the rate of item collection and supports informative output to the console. import logger _markers = [] def add_marker(): items = {} for i in Items: items = num_items(i) _markers.append((get_time(), items)) return len(_markers) - 1 # Returns marker creation time and items amount def get_marker_info(marker): return _markers[marker] def calc_item_rate(item, start_marker = 0, end_marker = len(_markers) - 1): d_seconds = _markers[end_marker][0] - _markers[start_marker][0] d_items = _markers[end_marker][1][item] - _markers[start_marker][1][item] item_rate = d_items / d_seconds return item_rate, d_items, d_seconds def log_item_rate(item, start_marker = 0, end_marker = len(_markers) - 1): rate, items, seconds = calc_item_rate(item, start_marker, end_marker) item, rate, items, seconds = str(item), str(rate), str(items), str(seconds) # e.g. [3706.85] [INFO] Got 128 of Items.Water over 5 second(s) (Rate: 25.58/s) logger.info("Got " + items + " of " + item + " over " + seconds + " second(s) (Rate: " + rate + "/s)")[/code] Ограничения О модуле Этот модуль позволяет создавать ограничения по времени, по количеству ресурсов, а также кастомные ограничения для вашего кода. Код может проверять, были ли исчерпаны эти лимиты, и выполнять нужные действия в этом случае. Основная особенность - полиморфизм. Ваш код может проверять лимиты, не заботясь о том, какие типы лимитов переданы. Функции Имя Параметры Описание create_time_limit seconds - время, когда лимит истечёт (в секундах) Создаёт и возвращает лимит, который истечёт в указанное время. create_delta_time_limit delta_seconds - через сколько секунд истечёт лимит Создаёт и возвращает лимит, который истечёт через указанное количество секунд. create_tick_limit ticks - количество тиков, при котором лимит истечёт Создаёт и возвращает лимит, который истечёт при достижении указанного количества тиков. create_delta_tick_limit delta_ticks - через сколько тиков истечёт лимит Создаёт и возвращает лимит, который истечёт через указанное количество тиков. create_max_item_limit item - объект типа Item, для которого создаётся лимит amount - количество, при достижении или превышении которого лимит истечёт Создаёт и возвращает лимит, который истечёт, когда количество указанного предмета станет равно или больше заданного значения. create_delta_max_item_limit item - объект типа Item, для которого создаётся лимит delta_amount - прирост количества, при достижении (текущего + указанного) или превышении которого лимит истечёт Создаёт и возвращает лимит, который истечёт, когда количество предмета увеличится на заданную величину или больше относительно текущего значения. create_min_item_limit item - объект типа Item, для которого создаётся лимит amount - количество, при достижении или снижении до которого лимит истечёт Создаёт и возвращает лимит, который истечёт, когда количество предмета станет равно или меньше заданного значения. create_delta_min_item_limit item - объект типа Item, для которого создаётся лимит delta_amount - уменьшение количества, при достижении (текущего - указанного) или ниже которого лимит истечёт Создаёт и возвращает лимит, который истечёт, когда количество предмета уменьшится на заданную величину или меньше относительно текущего значения. is_limit_exceeded limit - объект лимита Возвращает True, если переданный лимит был превышен, иначе False. is_any_limit_exceeded limits - список лимитов Возвращает True, если превышен хотя бы один лимит из списка. is_all_limits_exceeded limits - список лимитов Возвращает True, если превышены все лимиты из списка. Пример использования Лимит по времени Вставьте в новое окно такой код: import limiter clear() # Create 7-second limit limit = limiter.create_delta_time_limit(7) # do_a_flip until the limit is exceeded t1 = get_time() while not limiter.is_limit_exceeded(limit): do_a_flip() t2 = get_time() # Should print ~7 seconds print(t2 - t1) Данный код создаёт ограничение на 7 секунд и заставляет дрона делать сальто, пока лимит не будет превышен. Лимит по ресурсам Вставьте в новое окно такой код: import limiter clear() set_world_size(10) # Create a limit of 5120 hay limit = limiter.create_delta_max_item_limit(Items.Hay, 5120) # harvest hay until the limit is exceeded n1 = num_items(Items.Hay) while not limiter.is_limit_exceeded(limit): harvest() move(North) n2 = num_items(Items.Hay) # Should print 5120 print(n2 - n1) Данный код создаёт ограничение на 5120 сена и заставляет дрона собирать траву, пока лимит не будет превышен. Как это выглядит в игре: Код модуляㅤ Вставьте этот код в окно с именем limiter: # Limiter by ksm (https://steamcommunity.com/id/ksm2004/) # This module allows you to create limits based on time, numberof items, # and custom limits for your code. # -- General -- # def create_limit(comparator_func, getter_func, compare_value): return (comparator_func, getter_func, compare_value) def create_delta_limit(comparator_func, getter_func, compare_delta_value): compare_value = getter_func() + compare_delta_value return create_limit(comparator_func, getter_func, compare_value) def is_limit_exceeded(limit): comparator_func = limit[0] curr_value = limit[1]() compare_value = limit[2] return comparator_func(curr_value, compare_value) def is_any_limit_exceeded(limits): for l in limits: if is_limit_exceeded(l): return True return False def is_all_limits_exceeded(limits): for l in limits: if not is_limit_exceeded(l): return False return True # -- Comparators -- # def greater(a, b): return a &gt; b def greater_or_equal(a, b): return a &gt;= b def less(a, b): return a &lt; b def less_or_equal(a, b): return a &lt;= b def equal(a, b): return a == b # -- Time limit -- # def create_time_limit(seconds): return create_limit(greater_or_equal, get_time, seconds) def create_delta_time_limit(delta_seconds): return create_delta_limit(greater_or_equal, get_time, delta_seconds) # -- Tick limit -- # def create_tick_limit(ticks): return create_limit(greater_or_equal, get_tick_count, ticks) def create_delta_tick_limit(delta_ticks): return create_delta_limit(greater_or_equal, get_tick_count, delta_ticks) # -- Item limit -- # def _get_item_getter(item): def getter(): return num_items(item) return getter def create_max_item_limit(item, amount): return create_limit(greater_or_equal, _get_item_getter(item), amount) def create_delta_max_item_limit(item, delta_amount): return create_delta_limit(greater_or_equal, _get_item_getter(item), delta_amount) def create_min_item_limit(item, amount): return create_limit(less_or_equal, _get_item_getter(item), amount) def create_delta_min_item_limit(item, delta_amount): return create_limit(less_or_equal, _get_item_getter(item), delta_amount) Кастомные ограничения Создание кастомных ограничений Помимо лимитов по времени, тикам и ресурсам, вы можете создавать собственные (кастомные) лимиты. Для этого требуются три элемента: Getter-функция - возвращает текущее значение, которое будет использоваться для проверки лимита. Например, для лимита по времени это get_time. Значение для сравнения - целевое значение, с которым лимит сравнивает результат работы getter-функции, чтобы определить, истёк ли лимит. Comparator-функция — принимает два параметра `a` и `b`: `a` - заданное значение для сравнения, `b` - текущее значение из getter-функции. Функция должна вернуть `True`, если лимит превышен, и `False`, если нет. В качестве Comparator-функций можно использовать готовые функции `greater`, `greater_or_equal`, `less`, `less_or_equal` и `equal`, определённые в этом же модуле. Они реализуют базовые операции сравнения: больше, больше или равно, меньше, меньше или равно и равно. После определения всех трёх элементов лимит создаётся с помощью: create_limit(comparator_func, getter_func, compare_value) или create_delta_limit(comparator_func, getter_func, compare_delta_value) Разница между обычными и дельта-лимитами заключается в том, что обычный лимит сравнивает значение напрямую, а дельта-лимит добавляет к текущему значению, полученному через getter-функцию, указанную дельту. Пример: `create_time_limit(5)` будет превышен ровно в момент, когда время станет равно 5 секунд, а `create_delta_time_limit(5)` — когда текущее значение `get_time()` увеличится на 5, то есть через 5 секунд после вызова. Пример кастомного ограничения Вставьте в новое окно такой код: import limiter move_count = 0 # Here we will count the number of movements def move_and_count(dir): global move_count move(dir) move_count += 1 # Define getter for out custom limit def getter(): return move_count # Define comparator for our custom limit def is_power_of_two(a, b): return a == b ** 2 set_world_size(3) set_execution_speed(3) # The limit will be expired when the number of steps = 4**2 = 16 limit = limiter.create_limit(is_power_of_two, getter, 4) while not limiter.is_limit_exceeded(limit): move_and_count(North) print(move_count) # It will print 16 Здесь создаётся лимит на количество движений: Getter - возвращает текущее количество совершённых движений. Целевое значение - 4. Comparator - лимит считается превышенным, когда количество движений становится равно квадрату целевого значения, то есть 16. Как это выглядит в игре: ㅤ Полезные функции и константы О модуле В этом модуле собраны полезные функции и константы, которые могут пригодиться при создании ферм. Функции и константы Имя Параметры Описание opposite_dirs N/A Словарь, где ключи - направления, а значения - противоположные им направления. harvest_if_can - Собирает урожай, если растение полностью созрело. wait_and_harvest water - нужно ли поливать растение, если оно пока не выросло. Ждёт, пока растение под дроном не вырастет, затем собирает его. do_on_every_cell cell_func - функция, выполняемая на каждой клетке фермы. Проходит по всем клеткам фермы и вызывает указанную функцию на каждой из них. do_on_grid cell_func - функция, выполняемая на каждой клетке сетки width - ширина сетки (по умолчанию get_world_size()) height - высота сетки (по умолчанию get_world_size()) Проходит по клеткам сетки змейкой и вызывает на каждой указанную функцию. move_to x - координата X, куда нужно попасть y - координата Y, куда нужно попасть can_warp - можно ли телепортироваться через край карты Двигается к заданным координатам. Учитывает, что иногда быстрее телепортироваться через край мира, чем лететь напрямую. Пример использования Вставьте в новое окно такой код: import helpers def plant_and_harvest(): helpers.harvest_if_can() if get_ground_type() != Grounds.Soil: till() plant(Entities.Carrot) clear() set_world_size(5) while True: helpers.do_on_every_cell(plant_and_harvest) Данный код создаёт ферму моркови: на каждой клетке высаживает и собирает урожай, но только если он созрел. Как это выглядит в игре: ㅤ Код модуля Вставьте этот код в окно с именем helpers: # Helpers by ksm (https://steamcommunity.com/id/ksm2004/) # This module provides several useful functions &amp; constants # -- Useful constants -- # opposite_dirs = {North: South, East: West, South: North, West: East} # -- Useful functions -- # def harvest_if_can(): if can_harvest(): harvest() def wait_and_harvest(water = False): while not can_harvest(): if water and get_water() &lt;= 0.75: use_item(Items.Water) harvest() # -- Movement functions -- # # Visit every cell in the farm, wrapping around edges, and call a function def do_on_every_cell(cell_func): sz = get_world_size() for _ in range(sz): for _ in range(sz): cell_func() move(North) move(East) # Visit every cell in the grid, moving in a snake pattern, and call a function def do_on_grid(cell_func, width = get_world_size(), height = get_world_size()): def do_column(): for _ in range(height - 1): cell_func() move(move_dir) move_dir = North for _ in range(width - 1): do_column() cell_func() move(East) move_dir = opposite_dirs[move_dir] do_column() cell_func() # Move to specific position in most efficient way: #- If flying straight to the target is faster (or can_warp == False), do it. #- If warping from the edge of the map is faster (and can_warp == True), do it. def move_to(x, y, can_warp = True): sz = get_world_size() def calc_dir_and_dist(target, curr, side): # If the target is is in the forward direction diff = target - curr if not can_warp or abs(diff) &lt;= sz / 2: # Flying toward the target is faster. dir = side dist = abs(diff) else: # Flying around the map is faster dir = opposite_dirs[side] dist = sz - abs(diff) # If the target is located "behind" the current direction, simply change direction. if diff &lt; 0: dir = opposite_dirs[dir] return (dir, dist) dir_x, move_x = calc_dir_and_dist(x, get_pos_x(), East) dir_y, move_y = calc_dir_and_dist(y, get_pos_y(), North) for _ in range(move_x): move(dir_x) for _ in range(move_y): move(dir_y) Шляпный бонус О модуле Вам когда-нибудь надоедало, что после вызова функции clear() ваша любимая шляпа спадала с дрона? Этот модуль поможет это исправить! Как использовать Всё просто: Откройте модуль и укажите вашу любимую шляпу в константе DEFAULT_HAT. Импортируйте модуль: from hat import clear Теперь при вызове стандартной функции clear() шляпа будет автоматически заменяться на выбранную вами. Как это выглядит в игре: ㅤ Код модуля Вставьте этот код в окно с именем hat: # Hat by ksm (https://steamcommunity.com/id/ksm2004/) # This module allows you to set a default hat that will remain even after calling clear(). # NOTE: In order for the clear() function to work properly, this module must be imported as follows: # `from hat import clear` # Set your favorite hat here! DEFAULT_HAT = Hats.Wizard_Hat _clear = clear def _clear_keep_hat(): _clear() change_hat(DEFAULT_HAT) clear = _clear_keep_hat change_hat(DEFAULT_HAT) Заключение Это всё, с чем я хотел поделиться! В основном, весь код по этой игре, который я находил в интернете - это готовые решения для ферм. Я же решил поделиться более утилитарным кодом, который лично мне сильно помог при написании основного кода и при дебаге. Буду рад услышать от вас отзывы и конструктивную критику, удачи! ㅤ ㅤ