struct_post 0.1.4.3__py3-none-any.whl → 0.1.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- struct_post/beam.py +125 -11
- struct_post/coupon.py +95 -48
- {struct_post-0.1.4.3.dist-info → struct_post-0.1.7.dist-info}/METADATA +2 -1
- struct_post-0.1.7.dist-info/RECORD +9 -0
- struct_post-0.1.4.3.dist-info/RECORD +0 -9
- {struct_post-0.1.4.3.dist-info → struct_post-0.1.7.dist-info}/WHEEL +0 -0
- {struct_post-0.1.4.3.dist-info → struct_post-0.1.7.dist-info}/licenses/LICENSE +0 -0
- {struct_post-0.1.4.3.dist-info → struct_post-0.1.7.dist-info}/top_level.txt +0 -0
struct_post/beam.py
CHANGED
@@ -1,20 +1,133 @@
|
|
1
|
+
from pandas import DataFrame
|
1
2
|
import pandas as pd
|
2
|
-
|
3
|
+
|
4
|
+
def beam_lvmdata_file(file_name, force_index=2, displ_index=3,
|
5
|
+
mid_lvdt_ind=None, left_lvdt_ind=None, right_lvdt_ind=None):
|
6
|
+
"""
|
7
|
+
Read a .lvm file and extract force, displacement, and LVDT data in groups.
|
8
|
+
|
9
|
+
Parameters
|
10
|
+
----------
|
11
|
+
file_name : str
|
12
|
+
Path to the .lvm file to read.
|
13
|
+
force_index : int, default=2
|
14
|
+
1-based column index for the force data.
|
15
|
+
displ_index : int, default=3
|
16
|
+
1-based column index for the displacement (stroke) data.
|
17
|
+
mid_lvdt_ind : int or list of int, optional
|
18
|
+
Column index/indices for the middle LVDTs.
|
19
|
+
left_lvdt_ind : int or list of int, optional
|
20
|
+
Column index/indices for the left LVDTs.
|
21
|
+
right_lvdt_ind : int or list of int, optional
|
22
|
+
Column index/indices for the right LVDTs.
|
23
|
+
|
24
|
+
Returns
|
25
|
+
-------
|
26
|
+
df_new : pandas.DataFrame
|
27
|
+
Extracted data as a DataFrame with columns renamed:
|
28
|
+
['Force (kN)', 'Stroke (mm)', 'Mid_1 (mm)', 'Mid_2 (mm)',
|
29
|
+
'Left_1 (mm)', 'Left_2 (mm)', 'Right_1 (mm)', 'Right_2 (mm)'].
|
30
|
+
Only existing columns are included; missing columns are ignored.
|
31
|
+
file_base_name : str
|
32
|
+
Base name of the file without the '.lvm' extension.
|
33
|
+
|
34
|
+
Notes
|
35
|
+
-----
|
36
|
+
- Automatically detects the start of the data by locating the last
|
37
|
+
occurrence of '***End_of_Header***' in the file.
|
38
|
+
- Converts all columns to numeric values; non-numeric entries
|
39
|
+
are coerced to NaN.
|
40
|
+
- The last column is dropped assuming it is empty.
|
41
|
+
- Single integer indices are automatically converted to lists.
|
42
|
+
- LVDT columns are combined in the order: mid -> left -> right.
|
43
|
+
"""
|
44
|
+
|
45
|
+
mid_lvdt_ind = mid_lvdt_ind or []
|
46
|
+
left_lvdt_ind = left_lvdt_ind or []
|
47
|
+
right_lvdt_ind = right_lvdt_ind or []
|
48
|
+
|
49
|
+
if isinstance(mid_lvdt_ind, int):
|
50
|
+
mid_lvdt_ind = [mid_lvdt_ind]
|
51
|
+
if isinstance(left_lvdt_ind, int):
|
52
|
+
left_lvdt_ind = [left_lvdt_ind]
|
53
|
+
if isinstance(right_lvdt_ind, int):
|
54
|
+
right_lvdt_ind = [right_lvdt_ind]
|
55
|
+
|
56
|
+
lvdt_indices = mid_lvdt_ind + left_lvdt_ind + right_lvdt_ind
|
57
|
+
|
58
|
+
with open(file_name, 'r') as f:
|
59
|
+
lines = f.readlines()
|
60
|
+
start_idx = max(i for i, line in enumerate(lines) if "***End_of_Header***" in line) + 1
|
61
|
+
df = pd.read_csv(file_name, sep="\t", skiprows=start_idx)
|
62
|
+
df = df.apply(pd.to_numeric, errors='coerce')
|
63
|
+
df = df.drop(df.columns[-1], axis=1)
|
64
|
+
|
65
|
+
user_indices = [force_index, displ_index] + lvdt_indices
|
66
|
+
existing_cols = [df.columns[i-1] for i in user_indices if i-1 < len(df.columns)]
|
67
|
+
|
68
|
+
df_new = df[existing_cols].copy()
|
69
|
+
|
70
|
+
col_names = ['Force (kN)','Stroke (mm)','Mid_1 (mm)','Mid_2 (mm)','Left_1 (mm)','Left_2 (mm)','Right_1 (mm)','Right_2 (mm)']
|
71
|
+
df_new.columns = col_names[:len(existing_cols)]
|
72
|
+
|
73
|
+
return df_new, file_name[:-4]
|
74
|
+
|
75
|
+
def four_point_bending (data: DataFrame,
|
3
76
|
width: float,
|
4
77
|
depth: float,
|
5
78
|
beam_span: float):
|
79
|
+
"""
|
80
|
+
Perform four-point bending analysis to calculate apparent and true modulus of elasticity.
|
81
|
+
|
82
|
+
Parameters
|
83
|
+
----------
|
84
|
+
data : tuple
|
85
|
+
A tuple containing:
|
86
|
+
- data[0] : pandas.DataFrame
|
87
|
+
Experimental dataset with columns:
|
88
|
+
- 'Moog Force_kN' : Applied load (kN).
|
89
|
+
- 'LVDT 1_mm' ... 'LVDT 6_mm' : Deflections from six LVDTs (mm).
|
90
|
+
- data[1] : str
|
91
|
+
Sample name identifier.
|
92
|
+
width : float
|
93
|
+
Beam specimen width (mm).
|
94
|
+
depth : float
|
95
|
+
Beam specimen depth (mm).
|
96
|
+
beam_span : float
|
97
|
+
Beam span length (mm).
|
98
|
+
|
99
|
+
Returns
|
100
|
+
-------
|
101
|
+
tuple
|
102
|
+
(sample_name, results) where:
|
103
|
+
- sample_name : str
|
104
|
+
Name of the processed sample.
|
105
|
+
- results : dict
|
106
|
+
Dictionary containing:
|
107
|
+
- "E_app" : float
|
108
|
+
Apparent modulus of elasticity (MPa).
|
109
|
+
- "E_true" : float
|
110
|
+
True modulus of elasticity (MPa).
|
111
|
+
|
112
|
+
Notes
|
113
|
+
-----
|
114
|
+
- Apparent modulus (E_app) is calculated from mid-span deflection (LVDT 3 & 4).
|
115
|
+
- True modulus (E_true) is calculated from relative deflection (mid-span vs. supports).
|
116
|
+
- Load range for regression is limited to 10–40% of ultimate load.
|
117
|
+
"""
|
118
|
+
|
6
119
|
import pandas as pd
|
7
120
|
import numpy as np
|
8
121
|
|
9
|
-
#
|
122
|
+
#Experimental test data post-process
|
10
123
|
sample_name = data[1]
|
11
|
-
force = data[0]['
|
12
|
-
delta_1 = abs(data[0]['
|
13
|
-
delta_2 = abs(data[0]['
|
14
|
-
delta_3 = abs(data[0]['
|
15
|
-
delta_4 = abs(data[0]['
|
16
|
-
delta_5 = abs(data[0]['
|
17
|
-
delta_6 = abs(data[0]['
|
124
|
+
force = data[0]['Force (kN)'] * 1000
|
125
|
+
delta_1 = abs(data[0]['Left_1 (mm)'])
|
126
|
+
delta_2 = abs(data[0]['Left_2 (mm)'])
|
127
|
+
delta_3 = abs(data[0]['Mid_1 (mm)'])
|
128
|
+
delta_4 = abs(data[0]['Mid_2 (mm)'])
|
129
|
+
delta_5 = abs(data[0]['Right_1 (mm)'])
|
130
|
+
delta_6 = abs(data[0]['Right_2 (mm)'])
|
18
131
|
|
19
132
|
F_ult = force.max()
|
20
133
|
f_b = (F_ult * beam_span) / (width * depth **2) #MPa
|
@@ -31,10 +144,10 @@ def four_point_bending (data: pd.DataFrame,
|
|
31
144
|
|
32
145
|
F_ms = force[calcs_reg]
|
33
146
|
delta_ms_calcs = delta_ms[calcs_reg]
|
34
|
-
|
147
|
+
delta_rel_calcs = delta_rel[calcs_reg]
|
35
148
|
|
36
149
|
Delta_ms, intercept_ms = np.polyfit(delta_ms_calcs,F_ms,1)
|
37
|
-
Delta_rel, intercept_rel = np.polyfit(
|
150
|
+
Delta_rel, intercept_rel = np.polyfit(delta_rel_calcs,F_ms,1)
|
38
151
|
|
39
152
|
E_app = (23/108) * (beam_span/depth)**3 * Delta_ms * (1/width)
|
40
153
|
E_true = (1/36) * (beam_span/depth)**3 * Delta_rel * (1/width)
|
@@ -47,3 +160,4 @@ def four_point_bending (data: pd.DataFrame,
|
|
47
160
|
print(f"Sample Name: {sample_name}")
|
48
161
|
print('-' * 40)
|
49
162
|
return sample_name, results
|
163
|
+
|
struct_post/coupon.py
CHANGED
@@ -1,10 +1,44 @@
|
|
1
|
-
def
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
def coupon_csvdata_read(testdata_file_name: str,
|
2
|
+
force_index: int,
|
3
|
+
strain_index: int):
|
4
|
+
"""
|
5
|
+
Read tensile coupon test data from a CSV file and extract force and strain columns.
|
6
|
+
|
7
|
+
Args:
|
8
|
+
testdata_file_name (str): Path to the CSV file containing the test data.
|
9
|
+
force_index (int): 1-based column index for the force data.
|
10
|
+
strain_index (int): 1-based column index for the strain data.
|
11
|
+
|
12
|
+
Returns:
|
13
|
+
tuple:
|
14
|
+
df_new (pd.DataFrame): DataFrame containing only 'Force' and 'Strain' columns.
|
15
|
+
sample_name (str): Name of the sample extracted from the file name (without extension).
|
16
|
+
|
17
|
+
Notes:
|
18
|
+
- The CSV file is expected to have a header in the first row.
|
19
|
+
- The second row is skipped during reading (`skiprows=[1]`).
|
20
|
+
- The first column is treated as the index column (`index_col=0`).
|
21
|
+
- Force and strain columns are extracted based on the provided 1-based indices.
|
22
|
+
"""
|
23
|
+
|
24
|
+
import pandas as pd
|
25
|
+
df = pd.read_csv(testdata_file_name, skiprows=[1])
|
26
|
+
Force = df[df.columns[force_index - 1]]
|
27
|
+
Strain = df[df.columns[strain_index - 1]]
|
28
|
+
df_new = pd.concat([Force, Strain], axis=1)
|
29
|
+
df_new.columns = ['Force', 'Strain']
|
30
|
+
sample_name = testdata_file_name[:-4]
|
31
|
+
return sample_name, df_new
|
32
|
+
|
33
|
+
def coupon_test_analysis (sample_name: str,
|
34
|
+
Force: float,
|
35
|
+
Strain: float,
|
36
|
+
thickness: float = 2.5,
|
37
|
+
width: float = 10,
|
38
|
+
showfig: bool = True,
|
39
|
+
savefig: bool = False,
|
40
|
+
low_bound: float = 0.1,
|
41
|
+
up_bound: float = 0.3,
|
8
42
|
):
|
9
43
|
"""
|
10
44
|
Post-process a tensile coupon test and plot stress-strain curve.
|
@@ -25,36 +59,27 @@ def coupon_test_analysis (testdata_file_name: str,
|
|
25
59
|
import numpy as np
|
26
60
|
import matplotlib.pyplot as plt
|
27
61
|
#%matplotlib widget
|
62
|
+
|
28
63
|
# Constants
|
29
|
-
thickness # mm
|
30
|
-
width # mm
|
31
64
|
area = thickness * width # Calculate the area of the specimen
|
32
65
|
|
33
66
|
# Load tensile test data
|
34
|
-
|
35
|
-
|
36
|
-
#df.columns = [f"{col[0]} {col[1]}" for col in df.columns]
|
37
|
-
|
38
|
-
# Extract relevant columns
|
39
|
-
#time = df["Time (sec)"]
|
40
|
-
#displacement = df["Crosshead separation (mm)"]
|
41
|
-
force = df[df.columns[1]]
|
42
|
-
elongation = df[df.columns[2]]
|
43
|
-
strain = elongation # Strain in mm/mm
|
67
|
+
|
68
|
+
strain = Strain # Strain in mm/mm
|
44
69
|
|
45
70
|
# Calculate stress and strain
|
46
|
-
force =
|
47
|
-
stress = (force / area) # N/
|
71
|
+
force = Force * 1000 # Convert kN to N
|
72
|
+
stress = (force / area) # N/mm^2 or MPa
|
48
73
|
uts = stress.max()
|
49
74
|
|
50
75
|
#find the data before uts
|
51
76
|
idx_peak = np.argmax(stress)
|
52
|
-
strain_up =
|
77
|
+
strain_up = Strain[:idx_peak+1]
|
53
78
|
stress_up = stress[:idx_peak+1]
|
54
79
|
|
55
|
-
#Boundary for
|
56
|
-
lower_bound =
|
57
|
-
upper_bound =
|
80
|
+
#Boundary for [low bound] - [up bound] of uts
|
81
|
+
lower_bound = low_bound * uts
|
82
|
+
upper_bound = up_bound * uts
|
58
83
|
|
59
84
|
elastic_reg = (lower_bound <= stress_up) & (stress_up <= upper_bound)
|
60
85
|
|
@@ -66,8 +91,8 @@ def coupon_test_analysis (testdata_file_name: str,
|
|
66
91
|
E_GPa = E / 1000 # Convert MPa to GPa
|
67
92
|
#print(f"Intercept: {intercept} MPa")
|
68
93
|
|
69
|
-
# Select over
|
70
|
-
strain_new =
|
94
|
+
# Select over [lower bound] of UTS, as yield stress will over [lower bound] uts
|
95
|
+
strain_new = strain
|
71
96
|
stress_new = force / area
|
72
97
|
mask = (lower_bound <= stress)
|
73
98
|
strain_mask = strain_new[mask]
|
@@ -78,7 +103,7 @@ def coupon_test_analysis (testdata_file_name: str,
|
|
78
103
|
|
79
104
|
#Find the Yield strength
|
80
105
|
diff = stress_mask - offset_line
|
81
|
-
cross_index = np.where(diff <= 0)[0][0]
|
106
|
+
cross_index = np.where(diff <= 0)[0][0] +1
|
82
107
|
x1 = strain_mask[cross_index-1]
|
83
108
|
x2 = strain_mask[cross_index]
|
84
109
|
y1 = diff[cross_index-1]
|
@@ -98,7 +123,7 @@ def coupon_test_analysis (testdata_file_name: str,
|
|
98
123
|
|
99
124
|
ax.set_xlabel('Strain (mm/mm)')
|
100
125
|
ax.set_ylabel('Stress (MPa)')
|
101
|
-
ax.set_title(
|
126
|
+
ax.set_title(sample_name + ' Stress-Strain Curve with Mechanical Properties')
|
102
127
|
ax.legend()
|
103
128
|
ax.grid(True)
|
104
129
|
ax.set_ylim(0, 1.2 *uts)
|
@@ -111,10 +136,10 @@ def coupon_test_analysis (testdata_file_name: str,
|
|
111
136
|
|
112
137
|
# Save fig or not
|
113
138
|
if savefig == True:
|
114
|
-
fig.savefig(
|
139
|
+
fig.savefig(sample_name, dpi=300, bbox_inches='tight')
|
115
140
|
|
116
141
|
# Print results
|
117
|
-
print(f"Sample: {
|
142
|
+
print(f"Sample: {sample_name}")
|
118
143
|
print(f"Young's Modulus (E): {E:.2f} MPa")
|
119
144
|
print(f"Ultimate Tensile Strength (UTS): {uts:.2f} MPa")
|
120
145
|
print(f"Yield Strength: {yield_strength:.2f} MPa")
|
@@ -126,7 +151,7 @@ def coupon_test_analysis (testdata_file_name: str,
|
|
126
151
|
"UTS_MPa": uts,
|
127
152
|
"Yield_Strength_MPa": yield_strength
|
128
153
|
}
|
129
|
-
return
|
154
|
+
return sample_name, results
|
130
155
|
|
131
156
|
def coupon_sample_geodata_read (Excelfile_name: str):
|
132
157
|
'''
|
@@ -155,39 +180,61 @@ def coupon_sample_geodata_read (Excelfile_name: str):
|
|
155
180
|
for row in ws.iter_rows(min_row=2, values_only=True):
|
156
181
|
if all(cell is None for cell in row): # skip empty
|
157
182
|
continue
|
158
|
-
# 取前三列数据
|
159
183
|
sample_file_name = str (row[0] + ".csv")
|
160
184
|
sample_name = coupon_SampleDetails(row[0], row[1], row[2], sample_file_name)
|
161
185
|
samples.append(sample_name)
|
162
186
|
return samples
|
163
187
|
|
164
188
|
def coupon_batch_analysis(Coupon_geodata: str,
|
165
|
-
|
166
|
-
|
189
|
+
force_index: float,
|
190
|
+
strain_index:float,
|
191
|
+
showfig: bool = True,
|
192
|
+
savefig: bool = False):
|
167
193
|
"""
|
168
|
-
Perform batch analysis on a list of samples and return
|
194
|
+
Perform batch analysis on a list of tensile coupon samples and return their results.
|
169
195
|
|
170
196
|
Parameters
|
171
197
|
----------
|
172
|
-
Coupon_geodata : list
|
198
|
+
Coupon_geodata : list of SampleDetails
|
173
199
|
A list of SampleDetails objects, each containing:
|
174
|
-
- sample_file_name :
|
175
|
-
|
176
|
-
-
|
200
|
+
- sample_file_name : str
|
201
|
+
Path to the sample CSV file.
|
202
|
+
- thickness : float
|
203
|
+
Sample thickness (mm).
|
204
|
+
- width : float
|
205
|
+
Sample width (mm).
|
206
|
+
force_index : int
|
207
|
+
Column index of the Force data in the CSV file (1-based).
|
208
|
+
strain_index : int
|
209
|
+
Column index of the Strain data in the CSV file (1-based).
|
210
|
+
showfig : bool, optional
|
211
|
+
Whether to display stress-strain plots during analysis. Default is True.
|
177
212
|
savefig : bool, optional
|
178
|
-
Whether to save the
|
213
|
+
Whether to save the stress-strain plots to files. Default is False.
|
179
214
|
|
180
215
|
Returns
|
181
216
|
-------
|
182
|
-
list
|
217
|
+
list of SampleAnalysisResults
|
183
218
|
A list of SampleAnalysisResults objects, each containing:
|
184
|
-
-
|
185
|
-
|
186
|
-
-
|
219
|
+
- sample_name : str
|
220
|
+
Name of the processed sample.
|
221
|
+
- modulus_of_elasticity : float
|
222
|
+
Elastic modulus (E_GPa).
|
223
|
+
- ultimate_tensile_strength : float
|
224
|
+
Ultimate tensile strength (UTS_MPa).
|
225
|
+
- yield_strength : float
|
226
|
+
Yield strength (Yield_Strength_MPa).
|
187
227
|
"""
|
188
228
|
SARS = []
|
189
229
|
for Coupon_detail in Coupon_geodata:
|
190
|
-
|
230
|
+
csvdata = coupon_csvdata_read(Coupon_detail.sample_file_name,force_index,strain_index)
|
231
|
+
result = coupon_test_analysis(Coupon_detail.sample_file_name[:-4],
|
232
|
+
csvdata[1]['Force'],
|
233
|
+
csvdata[1]['Strain'],
|
234
|
+
Coupon_detail.thickness,
|
235
|
+
Coupon_detail.width,
|
236
|
+
showfig,
|
237
|
+
savefig)
|
191
238
|
SAR = coupon_SampleAnalysisResults(result[0], result[1]['E_MPa'], result[1]['UTS_MPa'], result[1]['Yield_Strength_MPa'])
|
192
239
|
SARS.append(SAR)
|
193
240
|
return SARS
|
@@ -237,7 +284,7 @@ def coupon_results_save(Excelfile_name: str, analysis_results: list):
|
|
237
284
|
print('The coupon test data analysis is complete.')
|
238
285
|
|
239
286
|
from dataclasses import dataclass
|
240
|
-
@dataclass
|
287
|
+
@dataclass
|
241
288
|
class coupon_SampleDetails:
|
242
289
|
"""
|
243
290
|
Holds basic information for a sample.
|
@@ -258,7 +305,7 @@ class coupon_SampleDetails:
|
|
258
305
|
thickness: float
|
259
306
|
sample_file_name: str
|
260
307
|
|
261
|
-
@dataclass
|
308
|
+
@dataclass
|
262
309
|
class coupon_SampleAnalysisResults:
|
263
310
|
"""
|
264
311
|
Stores the analysis results for a sample after mechanical testing.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: struct_post
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.7
|
4
4
|
Summary: A module designed to analyse common structural test results.
|
5
5
|
Requires-Python: >=3.10
|
6
6
|
Description-Content-Type: text/markdown
|
@@ -8,6 +8,7 @@ License-File: LICENSE
|
|
8
8
|
Requires-Dist: matplotlib>=3.10.6
|
9
9
|
Requires-Dist: openpyxl>=3.1.5
|
10
10
|
Requires-Dist: pandas>=2.3.2
|
11
|
+
Requires-Dist: requests>=2.32.5
|
11
12
|
Dynamic: license-file
|
12
13
|
|
13
14
|
# struct_post
|
@@ -0,0 +1,9 @@
|
|
1
|
+
struct_post/__init__.py,sha256=aNaAaoGGLodY5FTsVGCnUhzuXW9F50Mi_7xm-nQ-xFg,182
|
2
|
+
struct_post/beam.py,sha256=ftoh-J_7SCJUdptUnLgCXrvvHSKyACr0D8ZFJT0358s,5748
|
3
|
+
struct_post/coupon.py,sha256=vLHHSc37DaZFYQmx8zDHpa0S0CEgPlfbtedx9gGZY6o,11886
|
4
|
+
struct_post/read_lvm_file.py,sha256=3x-vbkgEQ-G3f939euIMqwjzVEt9zHtvNneYd1-ViDw,2539
|
5
|
+
struct_post-0.1.7.dist-info/licenses/LICENSE,sha256=0KCwPGoSiY1zA6U97FZJob9MJbaJOo6sRZF-xv6A1YI,1089
|
6
|
+
struct_post-0.1.7.dist-info/METADATA,sha256=i34uSxS4iIRHSFZHE6qXm2b2OxY9nNjaJ0Wc8oZj6v0,689
|
7
|
+
struct_post-0.1.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
8
|
+
struct_post-0.1.7.dist-info/top_level.txt,sha256=jgiqPN0SMTMUomzOey9HfIrScTFmOzyuLpwIJ-Sz1-0,12
|
9
|
+
struct_post-0.1.7.dist-info/RECORD,,
|
@@ -1,9 +0,0 @@
|
|
1
|
-
struct_post/__init__.py,sha256=aNaAaoGGLodY5FTsVGCnUhzuXW9F50Mi_7xm-nQ-xFg,182
|
2
|
-
struct_post/beam.py,sha256=y-dV-taU1JNcyZYVTeJDe0i2aOkDoCUp4Ar5I8QC9iw,1495
|
3
|
-
struct_post/coupon.py,sha256=pi-aGs-EnKosq7QwPR1unskTVoNZ8kZ3o3gQjlFSf34,9835
|
4
|
-
struct_post/read_lvm_file.py,sha256=3x-vbkgEQ-G3f939euIMqwjzVEt9zHtvNneYd1-ViDw,2539
|
5
|
-
struct_post-0.1.4.3.dist-info/licenses/LICENSE,sha256=0KCwPGoSiY1zA6U97FZJob9MJbaJOo6sRZF-xv6A1YI,1089
|
6
|
-
struct_post-0.1.4.3.dist-info/METADATA,sha256=R4qNtqJsWhPf2MLAK6z063xNdw3gbGOsUTUg52nozfE,658
|
7
|
-
struct_post-0.1.4.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
8
|
-
struct_post-0.1.4.3.dist-info/top_level.txt,sha256=jgiqPN0SMTMUomzOey9HfIrScTFmOzyuLpwIJ-Sz1-0,12
|
9
|
-
struct_post-0.1.4.3.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|