Ich bin relativ neu in python und versuche mich darin. Ich habe folgendes Problem. Ich habe in einer txt Datei eine Masse an Profilen mit folgender Struktur:
Code: Alles auswählen
CROSS_SECTION {
name = 390037
distance_coord = 0.949
left_point_global_coords = (23891.970, 213016.040, 880.280)
orientation_angle = 324.347960
main_channel_range = (29.869, 90.058)
bottom_range = (35.336,85.860)
friction_ranges = ((0.000,35.33600), (35.336,85.8600), (85.860,107.74400))
friction_coefficients = (18,25,18)
node_coords = ((0.000,880.280),(3.605,880.210),(6.191,879.790),(11.609,876.350),(21.613,876.500),(29.869,876.300),(32.011,875.210),(33.538,874.330),(34.606,873.650),(35.336,872.410),(38.125,872.770),(40.295,872.760),(42.740,872.880),(45.046,873.220),(49.633,873.270),(53.704,873.670),(67.757,874.340),(77.065,873.950),(81.889,873.880),(85.860,873.800),(87.572,875.060),(90.058,876.450),(97.332,876.380),(107.744,881.300))
theta_critic = -1.0
SOIL_DEF {
index = 2
range = (35.336,85.860)
}
}
Ich versuche oder will es schaffen, dass das Skript untersucht welche node_coords innerhalb der bottom_range liegen und dann auch das Profil anzeigt welches die meisten Punkte innerhalb der range hat. (das funktioniert auch schon)
Wo ich scheitere ist, dass ich dann gerne hätte, dass er ausgehend von dem mit den meisten Punkten innerhalb der range, die anderen Profile so adaptiert, dass diese dann auch innerhalb der bottom_range Punkte hinzugefügt bekommen (normal verteilt), sodass schlussendlich dann alle Profile die gleiche Punktezahl in der bottom_range aufweisen. (die Anzahl von dem vorher rausgefiltertem mit den meisten Punkten)
Aktuell habe ich diesen Code. Da funktioniert das mit den Punkten einfügen aber noch garnicht. kann mir da jemand helfen?
Vielen Dank
Code: Alles auswählen
import re
def count_points_within_range(node_coords, bottom_range):
count = 0
for x, _ in node_coords:
if bottom_range[0] <= x <= bottom_range[1]:
count += 1
return count
def distribute_points_evenly(start, end, existing_points, total_points):
points = set(existing_points)
while len(points) < total_points:
step = (end - start) / (total_points - 1)
new_points = [start + i * step for i in range(total_points) if start + i * step not in points]
points.update(new_points)
return sorted(list(points))
def extract_data_from_profile(profile_text):
# Angepasster regulärer Ausdruck, der auch negative Zahlen erfasst
node_coords_match = re.search(r'node_coords\s+=\s+\((((-\d+|\d+)\.\d+,(?:-\d+|\d+)\.\d+),?\s*)+\)', profile_text)
bottom_range_match = re.search(r'bottom_range\s+=\s+\(((-\d+|\d+)\.\d+,(-\d+|\d+)\.\d+)\)', profile_text)
if node_coords_match and bottom_range_match:
node_coords_str = node_coords_match.group(1)
node_coords_raw = re.findall(r'\(((-\d+|\d+)\.\d+,(?:-\d+|\d+)\.\d+)\)', node_coords_str)
node_coords = [(float(x), float(z)) for x, z in node_coords_raw]
bottom_range = tuple(map(float, bottom_range_match.groups()))
return node_coords, bottom_range
else:
return None, None
def add_points_to_profile(node_coords, bottom_range, max_points):
existing_points_in_range = [coord for coord in node_coords if bottom_range[0] <= coord[0] <= bottom_range[1]]
num_existing_points = len(existing_points_in_range)
if num_existing_points < max_points:
# Bestimme die Anzahl der hinzuzufügenden Punkte
points_to_add = max_points - num_existing_points
new_points = []
# Berechne die Positionen für die neuen Punkte
for i in range(1, points_to_add + 1):
x = bottom_range[0] + (bottom_range[1] - bottom_range[0]) * i / (points_to_add + 1)
# Finde den nächstgelegenen z-Wert zu diesem x-Wert
_, nearest_z = min(existing_points_in_range, key=lambda coord: abs(coord[0] - x))
new_points.append((x, nearest_z))
# Füge die neuen Punkte zur Liste hinzu
node_coords.extend(new_points)
node_coords.sort(key=lambda coord: coord[0])
return node_coords
def modify_profiles(content, max_points):
modified_profiles = []
profiles = content.split('CROSS_SECTION')[1:] # Trenne die Profile
for profile_text in profiles:
header, rest = profile_text.split('node_coords', 1)
coords_text, footer = rest.split(')', 1)
node_coords, bottom_range = extract_data_from_profile('node_coords' + coords_text + ')')
if node_coords and bottom_range:
# Füge Punkte hinzu und erhalte die modifizierten node_coords
modified_node_coords = add_points_to_profile(node_coords, bottom_range, max_points)
# Erstelle den aktualisierten node_coords Teil als String
updated_coords_str = "node_coords = " + str(modified_node_coords).replace("'", "").replace(",", ", ")
# Rekonstruiere das Profil
modified_profile = header + updated_coords_str + ')' + footer
else:
modified_profile = profile_text
modified_profiles.append('CROSS_SECTION ' + modified_profile)
return ''.join(modified_profiles)
# Finden des Profils mit den meisten Punkten innerhalb des bottom_range
def find_profile_with_most_points(file_path):
with open(file_path, 'r') as file:
content = file.read()
profiles = content.split('CROSS_SECTION')[1:] # Profile trennen
max_points = 0
for profile in profiles:
node_coords, bottom_range = extract_data_from_profile(profile)
if node_coords and bottom_range:
count = count_points_within_range(node_coords, bottom_range)
if count > max_points:
max_points = count
return max_points
# Hauptteil des Skriptes
file_path = 'C:/Users/xxx/Desktop/Profile_Anpassen/TM-P_06_AZ.txt'
max_points = find_profile_with_most_points(file_path)
with open(file_path, 'r') as file:
content = file.read()
modified_content = modify_profiles(content, max_points)
new_file_path = 'C:/Users/xxx/Desktop/Profile_Anpassen/TM-P_06_AZ_modified.txt'
with open(new_file_path, 'w') as new_file:
new_file.write(modified_content)