eshangj/stackoverflow_q_and_a_sample huggingface dataset:
Question: I'm attempting to program a simple turn-based game in Godot which relies on a Python websocket server for rules and state updates. To that end, I'm trying to make a simple prototype where I can input text into a Godot client, send it to the websocket, and receive some data back - an 'echo' configuration. I have server code outlined already: # server.py import socket HOST = "127.0.0.1" PORT = 65432 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.bind((HOST, PORT)) s.listen() conn, addr = s.accept() with conn: print(f"Connected by {addr}") while True: data = conn.recv(1024) if not data: break conn.sendall(data)  I could write a client in Python that sends data and receives the echo, but my efforts to do the same in Godot are sluggish at best. What might the minimum GDScript file for a client look like? Where should I look for tutorials on this sort of thing? I've looked at the Godot Official documentation in search of answers, then tutorials online. Maybe it's just my search engine acting up, but I haven't found anything that at once addresses my question and explains it in basic terms.

Answer: In Godot 4.2 WebSocketClient seems to not exist anymore, but in the editor I found the class WebSocketPeer with an example. I extended the example to show how to send a message to the socket server. extends Node # The URL we will connect to @export var websocket_url = "ws://localhost:8080" # Our WebSocketClient instance var socket = WebSocketPeer.new() func _ready(): var err = socket.connect_to_url(websocket_url) if err != OK: print("Unable to connect") set_process(false) else: print("connected") func _process(delta): socket.poll() var state = socket.get_ready_state() if state == WebSocketPeer.STATE_OPEN: while socket.get_available_packet_count(): _on_message_received(socket.get_packet()) elif state == WebSocketPeer.STATE_CLOSING: # Keep polling to achieve proper close. pass elif state == WebSocketPeer.STATE_CLOSED: var code = socket.get_close_code() var reason = socket.get_close_reason() _on_closed(code, reason) func _on_message_received(packet: PackedByteArray): var message = packet.get_string_from_utf8() print("WebSocket message received: %s" % message) func _on_closed(code, reason): print("WebSocket closed with code: %d, reason %s. Clean: %s" % [code, reason, code != -1]) set_process(false) # Stop processing. func _send_message(message : String): var state = socket.get_ready_state() if state == WebSocketPeer.STATE_OPEN: socket.send_text(message)  Basically it's similar to the WebSocketClient, but without the signals. In the process you poll the socket and check the current state. If it's open you get the available packets. Same for sending. If you directly want to send a string you can use the send_text function as in the example. To send a byte array you can use send.
Question: I have data in this form : data = {'Letter': ['A', 'B', 'C', 'D', 'E'], 'Type': ['Apples', 'Apples', 'Oranges', 'Oranges', 'Bananas'], 'Value': [1, 2, 0, 5, 6]} df = pd.DataFrame(data)  I want to combine a doughnut plot and a radar plot, where the outer ring will be coloured according to the column "Type". import numpy as np import matplotlib.pyplot as plt import pandas as pd data = {'Letter': ['A', 'B', 'C', 'D', 'E'], 'Type': ['Apples', 'Apples', 'Oranges', 'Oranges', 'Bananas'], 'Value': [1, 2, 0, 5, 6]} df = pd.DataFrame(data) num_categories = len(df) angles = np.linspace(0, 2 * np.pi, num_categories, endpoint=False).tolist() values = df['Value'].tolist() values += values[:1] angles += angles[:1] plt.figure(figsize=(8, 8)) plt.polar(angles, values, marker='o', linestyle='-', linewidth=2) plt.fill(angles, values, alpha=0.25) plt.xticks(angles[:-1], df['Letter']) types = df['Type'].unique() color_map = {t: i / len(types) for i, t in enumerate(types)} colors = df['Type'].map(color_map) plt.fill(angles, values, color=plt.cm.viridis(colors), alpha=0.25) plt.show()  I want this to look like this : 

Answer: You could use Wedge: from matplotlib.patches import Wedge from matplotlib import colormaps ax = plt.gca() cmap = plt.cm.viridis.resampled(df['Type'].nunique()) # group consecutive types g = df['Type'].ne(df['Type'].shift()).cumsum() # set up colors per type colors = dict(zip(df['Type'].unique(), map(matplotlib.colors.to_hex, cmap.colors))) # {'Apples': '#440154', 'Oranges': '#21918c', 'Bananas': '#fde725'} # radius of wedge y = 0.49 # loop over groups for (_, name), grp in df.reset_index(drop=True).groupby([g, 'Type']): factor = 360/len(df) start = (grp.index[0]-0.5)*factor end = (grp.index[-1]+0.5)*factor ax.add_artist(Wedge((0.5, 0.5), y, start, end, width=0.01, color=colors[name], transform=ax.transAxes) )  Output:
Question: I have the following pandas dataframe and I would like a function that returns the ID's data with at least 1 True value in bool_1, 2 True values in bool_2 and 3 True values in bool_3 column, using the groupby function. index ID bool_1 bool_2 bool_3 0 7 True True True 1 7 False True True 2 7 False False True 3 8 True True True 4 8 True True True 5 8 False False True 6 9 True True True 7 9 True False True 8 9 True False True 9 9 True False False  As output I would expect complete data for ID 7 and 8 to be returned, since 9 has only 1 True value for bool_2. Any idea for that function? Thank you!

Answer: You can specify number of Trues in dictionary, so possible compare by DataFrame.ge for greate or equal count of Trues by aggregate sum and filter original DataFrame by boolean indexing with Series.isin: d = {'bool_1':1, 'bool_2':2,'bool_3':3} ids = df.groupby('ID')[list(d.keys())].sum().ge(d).all(axis=1) print (ids) ID 7 True 8 True 9 False dtype: bool out = df[df['ID'].isin(ids.index[ids])] print (out) index ID bool_1 bool_2 bool_3 0 0 7 True True True 1 1 7 False True True 2 2 7 False False True 3 3 8 True True True 4 4 8 True True True 5 5 8 False False True  Another idea is use GroupBy.transform for create boolean mask: d = {'bool_1':1, 'bool_2':2,'bool_3':3} mask = df.groupby('ID')[list(d.keys())].transform('sum').ge(d).all(axis=1) print (mask) 0 True 1 True 2 True 3 True 4 True 5 True 6 False 7 False 8 False 9 False dtype: bool out = df[mask] print (out) index ID bool_1 bool_2 bool_3 0 0 7 True True True 1 1 7 False True True 2 2 7 False False True 3 3 8 True True True 4 4 8 True True True 5 5 8 False False True
Question: I have a data frame exemplified as data = [['A', 10, {'Cc', 'Dd'}], ['B', 15, {'Aa', 'Dd', 'Cc', 'Ee'}], ['C', 14, {'Dd', 'Ee', 'Aa'}],['D', 3, {'Bb'}],['E', 3,{'Dd', 'Cc'}]] df = pd.DataFrame(data, columns=['type', 'val', 'others'])  I would like to perform some data processing on this dataset. For the 'type' column, I have introduced a dictionary as dic_type ={'A':0, 'B':1, 'C':2, 'D':3, 'E':4}  which brings the first column into a value using df["type"].replace(dic_type, inplace=True)  This column then looks good to me to carry out the rest of the analysis. However, I am unsure how to bring the values of the 'others' column into numbers. Each cell of the last column contains a list with various numbers of elements. The permutation of these elements, which may appear in some cells, should not be counted. For instance, the values for the first and last cell of the 'others' should be identical. Do you have any suggestions on getting this enumeration? My data frame has over 6000 cells, and I should perform this task as efficiently as possible.

Answer: If I understand you correctly, you need to assign a numerical code to the column others - which contains sets of values. You can convert the column values to frozenset and then apply pd.Categorical to it: df["others_codes"] = pd.Categorical(df["others"].apply(frozenset)).codes print(df)  Prints:  type val others others_codes 0 A 10 {Dd, Cc} 0 1 B 15 {Dd, Aa, Ee, Cc} 2 2 C 14 {Dd, Ee, Aa} 1 3 D 3 {Bb} 3 4 E 3 {Dd, Cc} 0
Question: I have used the following code to remove the default formating from the header in pandas. pd.io.formats.excel.ExcelFormatter.header_style = None  It was working previously, but now I am getting following error. pd.io.formats.excel.ExcelFormatter.header_style = None ^^^^^^^^^^^^^^^^^^^ AttributeError: module 'pandas.io.formats' has no attribute 'excel'  What could be the possible reason and solution? Are there any alternate method for this? Thanks. I have tried updating Pandas. But that did not help.

Answer: I tried on pandas <2 as well as pandas >2, it is working in both pandas versions. This should be the correct import: import pandas.io.formats.excel pandas.io.formats.excel.ExcelFormatter.header_style = None  related git : https://github.com/pandas-dev/pandas/issues/19386#issuecomment-851653196
Question: Showing a toy example with K=2 but the question is mostly relevant for high g cardinality and K>>1: df = pl.DataFrame(dict( g=[1, 2, 1, 2, 1, 2], v=[1, 2, 3, 4, 5, 6], )) K = 2 df.with_columns((col.v.shift(k+1).over('g').alias(f's{k}') for k in range(K)))  ╭─────┬─────┬──────┬──────╮ │ g ┆ v ┆ s0 ┆ s1 │ │ i64 ┆ i64 ┆ i64 ┆ i64 │ ╞═════╪═════╪══════╪══════╡ │ 1 ┆ 1 ┆ null ┆ null │ │ 2 ┆ 2 ┆ null ┆ null │ │ 1 ┆ 3 ┆ 1 ┆ null │ │ 2 ┆ 4 ┆ 2 ┆ null │ │ 1 ┆ 5 ┆ 3 ┆ 1 │ │ 2 ┆ 6 ┆ 4 ┆ 2 │ ╰─────┴─────┴──────┴──────╯  How can I make sure the grouping by g is done only once? Polars does not seem to optimize for this in the query plan. I would expect it to run as fast as: df.group_by('g').agg((col.v.shift(k+1).alias(f's{k}') for k in range(K))) 

Answer: Polars caches window expressions. While you may not see this represented in the query plan, the over grouping is only done once. Still, your over query will not run as fast as your group_by query. This is because over has to add the results back into the original data frame. A fairer comparison would be the query below, which will match the result of the over query. As you can see, an additional join is required. import polars as pl df = pl.DataFrame( { "g": [1, 2, 1, 2, 1, 2], "v": [1, 2, 3, 4, 5, 6], } ) K = 2 df_shift = ( df.group_by("g") .agg([pl.col("v")] + [pl.col("v").shift(k + 1).alias(f"s{k}") for k in range(K)]) .explode(["v"] + [f"s{k}" for k in range(K)]) ) result = df.join(df_shift, on=["g", "v"], how="left") print(result)  shape: (6, 4) ┌─────┬─────┬──────┬──────┐ │ g ┆ v ┆ s0 ┆ s1 │ │ --- ┆ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ i64 ┆ i64 │ ╞═════╪═════╪══════╪══════╡ │ 1 ┆ 1 ┆ null ┆ null │ │ 2 ┆ 2 ┆ null ┆ null │ │ 1 ┆ 3 ┆ 1 ┆ null │ │ 2 ┆ 4 ┆ 2 ┆ null │ │ 1 ┆ 5 ┆ 3 ┆ 1 │ │ 2 ┆ 6 ┆ 4 ┆ 2 │ └─────┴─────┴──────┴──────┘
Question: I'm developing a tracking script using Python and the Solana.py, installed via pip. The script uses websocket subscriptions to notify me when something happens on the Solana blockchain. My first approach was to watch a specific account: await websocket.account_subscribe(PublicKey('somekeyhere'))  But when doing ... from solana.publickey import PublicKey  I get the following error: from solana.publickey import PublicKey ModuleNotFoundError: No module named 'solana.publickey'  Solana.py is the latest version (0.31.0). I'm on Ubuntu 22.04 LTS and using Python 3.10.12. I found a workaround, just using another subscription method, that does not need any parameters: await websocket.logs_subscribe()  Then I analyze the output to my needs. That means, that I'm dealing with every single log on the Solana blockchains. It works, but it does not "feel right". And I would love to understand, what is going wrong when using the websocket.account_subscribe method. Any suggestions? Regards Kurt

Answer: Based on their github, it looks like what you need is Pubkey, not Publickey, taken from solders rather than solana. Have you tried this instead? from solders.pubkey import Pubkey  I haven't used their SDK before, so this might not solve your issue, but it was something I noted given your issue. Ref: solana.py Github
Question: Here's my question: I'm trying to filter an image based on the values of two coordinates. I can do this easily with a for loop: import numpy as np import matplotlib.pyplot as plt x = np.linspace(-1, 1, 101) y = np.linspace(-1, 1, 51) X, Y = np.meshgrid(x, y) Z = np.exp(X**2 + Y**2) newZ = np.zeros(Z.shape) for i, y_i in enumerate(y): for j, x_j in enumerate(x): if x_j > 0 and y_i > 0: newZ[i, j] = Z[i, j] else: newZ[i, j] = 0 plt.contourf(x, y, newZ) plt.show()  but I'm pretty sure there should be a way to do it by indexing (as it should be faster) like: Z = Z[y>0, x>0]  which doesn't work (IndexError: Shape mismatch) I assume I could do this with a mask using masked array perhaps (it seems they are doing something like that here), but I wonder if there is a simple one-liner in normal numpy that I can't seem to figure out. Thanks

Answer: Edit, you have to use numpy broadcasting: m = (y[:, None] > 0) | (x > 0) newZ = np.where(m, Z, 0) # OR m = (y[:, None] > 0) | (x > 0) newZ = np.zeros(Z.shape) newZ[m] = Z[m]  Demo: x = np.linspace(-1, 1, 11) y = np.linspace(-1, 1, 6) Z = np.arange(len(y)*len(x)).reshape(len(y), len(x)) m = (y[:, None] > 0) | (x > 0) newZ = np.zeros(Z.shape, dtype=int) newZ[m] = Z[m]  Output: >>> x array([-1. , -0.8, -0.6, -0.4, -0.2, 0. , 0.2, 0.4, 0.6, 0.8, 1. ]) >>> y array([-1. , -0.6, -0.2, 0.2, 0.6, 1. ]) >>> Z array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21], [22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32], [33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43], [44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54], [55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65]]) >>> newZ array([[ 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10], [ 0, 0, 0, 0, 0, 0, 17, 18, 19, 20, 21], [ 0, 0, 0, 0, 0, 0, 28, 29, 30, 31, 32], [33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43], [44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54], [55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65]])  With masked array: >>> np.ma.masked_array(Z, ~m, fill_value=0) masked_array( data=[[--, --, --, --, --, --, 6, 7, 8, 9, 10], [--, --, --, --, --, --, 17, 18, 19, 20, 21], [--, --, --, --, --, --, 28, 29, 30, 31, 32], [33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43], [44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54], [55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65]], mask=[[ True, True, True, True, True, True, False, False, False, False, False], [ True, True, True, True, True, True, False, False, False, False, False], [ True, True, True, True, True, True, False, False, False, False, False], [False, False, False, False, False, False, False, False, False, False, False], [False, False, False, False, False, False, False, False, False, False, False], [False, False, False, False, False, False, False, False, False, False, False]], fill_value=0)   IIUC, you are looking for np.where: newZ = np.where(Z>0, Z, 0)  Same as: m = Z>0 newZ = np.zeros(Z.shape) newZ[m] = Z[m]  Alternative with np.clip: newZ = np.clip(Z, 0, np.inf)
Question: I have some data recorded with timestamps using time.time(). I want to evaluate the data using pandas and convert the timestamps to datetime objects for better handling. However, when I try, all my timing data is off by one hour. This example reproduces the issue on my machine: import datetime as dt import pandas as pd origin = dt.datetime(2024, 1, 15).timestamp() timestamps = [origin + 3600 * i for i in range(10)] print([dt.datetime.fromtimestamp(t).isoformat() for t in timestamps]) print(pd.to_datetime(timestamps, unit='s'))  Output: ['2024-01-15T00:00:00', '2024-01-15T01:00:00', '2024-01-15T02:00:00', '2024-01-15T03:00:00', '2024-01-15T04:00:00', '2024-01-15T05:00:00', '2024-01-15T06:00:00', '2024-01-15T07:00:00', '2024-01-15T08:00:00', '2024-01-15T09:00:00'] DatetimeIndex(['2024-01-14 23:00:00', '2024-01-15 00:00:00', '2024-01-15 01:00:00', '2024-01-15 02:00:00', '2024-01-15 03:00:00', '2024-01-15 04:00:00', '2024-01-15 05:00:00', '2024-01-15 06:00:00', '2024-01-15 07:00:00', '2024-01-15 08:00:00'], dtype='datetime64[ns]', freq=None)  I am guessing that this has something to do with my timezone (I'm in UTC+1) but I'm confused as to how I should deal with this. If possible, I want to avoid explicitly specifying timezones and such (though I will do it if necessary). I want to just get the same times as I get with dt.datetime.fromtimestamp(). How do I do this?

Answer: You can use tz_convert to shift your datetime: >>> pd.to_datetime(timestamps, unit='s', utc=True).tz_convert('Europe/Paris') DatetimeIndex(['2024-01-15 00:00:00+01:00', '2024-01-15 01:00:00+01:00', '2024-01-15 02:00:00+01:00', '2024-01-15 03:00:00+01:00', '2024-01-15 04:00:00+01:00', '2024-01-15 05:00:00+01:00', '2024-01-15 06:00:00+01:00', '2024-01-15 07:00:00+01:00', '2024-01-15 08:00:00+01:00', '2024-01-15 09:00:00+01:00'], dtype='datetime64[ns, Europe/Paris]', freq=None)  You can replace Europe/Paris with Etc/GMT-1 or UTC+01:00 If you want to convert as naive timezone without lag, you can chain with tz_localize to remove timezone information: >>> (pd.to_datetime(timestamps, unit='s', utc=True) .tz_convert('UTC+01:00') .tz_localize(None)) DatetimeIndex(['2024-01-15 00:00:00', '2024-01-15 01:00:00', '2024-01-15 02:00:00', '2024-01-15 03:00:00', '2024-01-15 04:00:00', '2024-01-15 05:00:00', '2024-01-15 06:00:00', '2024-01-15 07:00:00', '2024-01-15 08:00:00', '2024-01-15 09:00:00'], dtype='datetime64[ns]', freq=None)  It all depends on the meaning you give to your timestamps (naive or timezone aware) If time.time() doesn't return the same value as pd.Timestamp().now(), you have to consider to use timezone to get the local time: >>> pd.to_datetime(time.time(), unit='s') 2024-01-15 16:12:49.276476672 >>> print(pd.Timestamp.now()) 2024-01-15 17:12:49.276847
Question: I'm trying to run a simple Streamlit app in my conda env. When I'm running the following app.py file: # Streamlit app import streamlit as st # prompt = st.chat_input("Say something") if prompt: st.write(f"User has sent the following prompt: {prompt}")  It returns the following error when running streamlit run app.py: Traceback (most recent call last): File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/streamlit/runtime/scriptrunner/script_runner.py", line 556, in _run_script exec(code, module.__dict__) File "/Users/quinten/Documents/app.py", line 11, in <module> prompt = st.chat_input("Say something") AttributeError: module 'streamlit' has no attribute 'chat_input'  I don't understand why this error happens. I used the newest Streamlit version. Also I don't understand why the error uses python3.9 while I use 3.12 in my environment. I check this blog, but this doesn't help unfortunately. So I was wondering if anyone knows why this happens?  I'm using the following versions: streamlit 1.30.0  And python: python --version Python 3.12.0 

Answer: Create a new virtual environment: python -m venv venv  Activate the virtual environment : source venv/bin/activate  Then install streamlit: pip install streamlit  Then you can run your app: streamlit run app.py  That way you can make sure that you are using the right version of streamlit. You can use conda to manage manage environments
Question: Given the sample data: data = [['john', 'test_1', pd.NA], ['john', 'test_2', 'fail'], ['john', 'test_3', 'fail'], ['mary', 'test_1', pd.NA], ['mary', 'test_2', 'fail'], ['mary', 'test_3', pd.NA], ['nick', 'test_1', pd.NA], ['liam', 'test_1', pd.NA], ['liam', 'test_2', pd.NA], ['jane', 'test_1', pd.NA], ['jane', 'test_2', 'pass'], ['jane', 'test_3', pd.NA], ['emma', 'test_1', pd.NA], ['emma', 'test_2', pd.NA], ['emma', 'test_3', 'fail']] df = pd.DataFrame(data, columns=['name', 'test', 'result'])  I'm having trouble trying to select the people that didn't failed test_2.  df = df.groupby('name').filter(lambda x : ((x.result != 'fail')).all())  The code above partially works by removing john and mary, the problem is that also removes emma because the condition doesn't apply to test_2 only. The following code also does not work for my desired output: df = df.groupby('name').filter(lambda x : ((x.test == 'test_2') & (x.result != 'fail')).all())  I'm sure my issue is more logic related, but I've have spent some hours trying to figure it out without success.

Answer: Determine who failed the test with boolean indexing and drop them with another boolean indexing and isin: # identify which names failed "test_2" drop = df.loc[df['test'].eq('test_2') & df['result'].eq('fail'), 'name'].unique() # ['john', 'mary'] # select the other names out = df[~df['name'].isin(drop)]  You code was incorrect since you were filtering for the users that took the "test_2" but didn't fail for all rows in the group The correct code with filter would have been: # do NOT keep users that ever passed "test_2" AND failed out = (df.groupby('name') .filter(lambda x : not ( (x.test == 'test_2') &(x.result == 'fail') ).any()) )  Or using De Morgan's laws: # keep users that always passed something other than "test_2" OR didn't fail # (equivalent to: never passed "test_2" AND failed) out = (df.groupby('name') .filter(lambda x : ( (x.test != 'test_2') | (x.result != 'fail') ).all()) )  Output:  name test result 6 nick test_1 <NA> 7 liam test_1 <NA> 8 liam test_2 <NA> 9 jane test_1 <NA> 10 jane test_2 pass 11 jane test_3 <NA> 12 emma test_1 <NA> 13 emma test_2 <NA> 14 emma test_3 fail
Question: Here's some data: my_dataframe = pd.DataFrame({'time': ["2024-1-1 09:00:00", "2024-1-1 15:00:00", "2024-1-1 21:00:00", "2024-1-2 09:00:00", "2024-1-2 15:00:00", "2024-1-2 21:00:00"], 'assists': [5, 7, 7, 9, 12, 9], 'rebounds': [11, 8, 10, 6, 6, 5], 'blocks': [4, 7, 7, 6, 5, 8]})   I want to select all data between noon and 10pm, i.e. rows 1-2 & 4-5. How can I do that? I tried using between_time, but it does not seem to work because (as far as I can tell) the time is a series in the data and not a timestamp. That suggests I need to first convert the series to a timestamp, but datetime.strptime does not seem to work because the time is not a string, and neither does series.to_timestamp (my_dataframe.iloc[:,0].to_timestamp() seems to raise an "unsupported Type RangeIndex" error).

Answer: You could convert your Series (converted to_datetime) to a DatetimeIndex to use DatetimeIndex.indexer_between_time to get the positions of the matching rows, and iloc to select them: keep = (pd.DatetimeIndex(pd.to_datetime(my_dataframe['time'])) .indexer_between_time('12:00', '22:00') ) # array([1, 2, 4, 5]) out = my_dataframe.iloc[keep]  Output:  time assists rebounds blocks 1 2024-1-1 15:00:00 7 8 7 2 2024-1-1 21:00:00 7 10 7 4 2024-1-2 15:00:00 12 6 5 5 2024-1-2 21:00:00 9 5 8  Or, use the datetime as index and between_time: out = (my_dataframe.set_index(pd.to_datetime(my_dataframe['time'])) .between_time('12:00', '22:00') )  Output:  time assists rebounds blocks time 2024-01-01 15:00:00 2024-1-1 15:00:00 7 8 7 2024-01-01 21:00:00 2024-1-1 21:00:00 7 10 7 2024-01-02 15:00:00 2024-1-2 15:00:00 12 6 5 2024-01-02 21:00:00 2024-1-2 21:00:00 9 5 8