SergeyO7 commited on
Commit
37a4c67
·
verified ·
1 Parent(s): d507774

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +39 -78
app.py CHANGED
@@ -9,14 +9,14 @@ from timezonefinder import TimezoneFinder
9
  import pytz
10
  import swisseph as swe
11
 
12
- # Constants and Configuration
13
- swe.set_ephe_path(None) # Initialize Swiss Ephemeris once at startup
14
 
15
  # Russian translations for planets
16
  PLANET_RU = {
17
- 'Sun': 'Солнце', 'Moon': 'Луна', 'Mercury': 'Меркурий',
18
- 'Venus': 'Венера', 'Mars': 'Марс', 'Jupiter': 'Юпитер',
19
- 'Saturn': 'Сатурн'
20
  }
21
 
22
  # Planet symbols for plotting
@@ -32,33 +32,23 @@ ZODIAC_SIGNS = [
32
  ]
33
 
34
  def parse_query(query):
35
- """
36
- Parse the query into date, time, and location.
37
- Args:
38
- query: String in format "PLadder YYYY-MM-DD HH:MM Location"
39
- Returns:
40
- tuple: (datetime, location, error_message)
41
- """
42
  if not query.startswith("PLadder "):
43
  return None, None, "Query must start with 'PLadder'"
44
 
45
  try:
46
- _, date_str, time_str, *location_parts = query.split(maxsplit=3)
47
- location = location_parts[0] if location_parts else ""
 
 
 
48
  dt = parser.parse(f"{date_str} {time_str}")
49
  return dt, location, None
50
  except ValueError as e:
51
  return None, None, f"Invalid format: {str(e)}"
52
 
53
  def get_utc_time(dt, location):
54
- """
55
- Convert local time to UTC using location's time zone.
56
- Args:
57
- dt: Local datetime
58
- location: String location
59
- Returns:
60
- tuple: (utc_dt, lat, lon, error_message)
61
- """
62
  geolocator = Nominatim(user_agent="pladder_app")
63
  try:
64
  loc = geolocator.geocode(location, timeout=10)
@@ -74,25 +64,17 @@ def get_utc_time(dt, location):
74
  local_dt = tz.localize(dt)
75
  utc_dt = local_dt.astimezone(pytz.UTC)
76
  return utc_dt, lat, lon, None
77
-
78
  except Exception as e:
79
- return None, None, None, f"Geocoding error: {str(e)}"
80
 
81
  def format_coords(lat, lon):
82
- """
83
- Format coordinates as degrees, minutes, seconds.
84
- Args:
85
- lat: Latitude in degrees
86
- lon: Longitude in degrees
87
- Returns:
88
- str: Formatted coordinates (e.g., "12°34'56" N, 98°45'32" E")
89
- """
90
  def dms(value, pos_dir, neg_dir):
91
  direction = pos_dir if value >= 0 else neg_dir
92
  abs_value = abs(value)
93
  degrees = int(abs_value)
94
  minutes = int((abs_value - degrees) * 60)
95
- seconds = round(((abs_value - degrees) * 60 - minutes) * 60)
96
 
97
  # Handle rounding overflow
98
  if seconds >= 60:
@@ -109,34 +91,26 @@ def format_coords(lat, lon):
109
  def lon_to_sign(lon_deg):
110
  """
111
  Convert ecliptic longitude to zodiac sign with position.
112
- Args:
113
- lon_deg: Longitude in degrees (0-360)
114
- Returns:
115
- str: Formatted sign and position (e.g., "Лев 12°34'")
116
  """
117
  sign_idx = int(lon_deg // 30)
118
  degrees_in_sign = lon_deg % 30
119
  degrees = int(degrees_in_sign)
120
  minutes = int((degrees_in_sign - degrees) * 60)
 
121
 
122
- # Handle rounding
 
 
 
123
  if minutes >= 60:
124
  minutes -= 60
125
  degrees += 1
126
 
127
- return f"{ZODIAC_SIGNS[sign_idx]} {degrees}°{minutes:02}'"
128
 
129
  def PLadder_ZSizes(utc_dt, lat, lon):
130
- """
131
- Calculate Planetary Ladder and Zone Sizes using Swiss Ephemeris.
132
- Args:
133
- utc_dt: UTC datetime
134
- lat: Latitude in degrees
135
- lon: Longitude in degrees
136
- Returns:
137
- dict: Contains PLadder, ZSizes, and longitudes
138
- """
139
- # Validate date range
140
  if not -13000 <= utc_dt.year <= 17000:
141
  return {"error": "Date out of supported range (-13,000–17,000 CE)"}
142
 
@@ -147,7 +121,7 @@ def PLadder_ZSizes(utc_dt, lat, lon):
147
  'Jupiter': swe.JUPITER, 'Saturn': swe.SATURN
148
  }
149
 
150
- # Calculate Julian Day with high precision
151
  jd_utc = swe.julday(
152
  utc_dt.year, utc_dt.month, utc_dt.day,
153
  utc_dt.hour + utc_dt.minute/60 + utc_dt.second/3600
@@ -190,7 +164,7 @@ def PLadder_ZSizes(utc_dt, lat, lon):
190
  else:
191
  X = 5
192
 
193
- # Format size and classification
194
  d = int(size)
195
  m = int((size - d) * 60)
196
  s = int(round(((size - d) * 60 - m) * 60))
@@ -217,29 +191,23 @@ def PLadder_ZSizes(utc_dt, lat, lon):
217
  return {
218
  'PLadder': PLadder,
219
  'ZSizes': ZSizes,
220
- 'longitudes': {k: v for k, v in longitudes.items()} # Raw degrees
221
  }
222
 
223
  def plot_pladder(PLadder):
224
- """
225
- Generate visualization of the planetary ladder.
226
- Args:
227
- PLadder: Ordered list of planets
228
- Returns:
229
- matplotlib Figure
230
- """
231
- fig, ax = plt.subplots(figsize=(8, 8))
232
 
233
- # Draw main triangle
234
  ax.plot([0, 1.5, 3, 0], [0, 3, 0, 0], 'k-', linewidth=2)
235
 
236
- # Draw horizontal divisions
237
- ax.plot([0.5, 2.5], [1, 1], 'k--', alpha=0.5)
238
- ax.plot([1, 2], [2, 2], 'k--', alpha=0.5)
239
 
240
- # Planet symbol positions
241
  symbol_positions = [
242
- (-0.2, 0.2), (0.3, 1.2), (0.8, 2.2),
243
  (1.5, 3.2), (2.2, 2.2), (2.7, 1.2), (3.2, 0.2)
244
  ]
245
 
@@ -247,25 +215,18 @@ def plot_pladder(PLadder):
247
  for (x, y), planet in zip(symbol_positions, PLadder):
248
  ax.text(x, y, PLANET_SYMBOLS[planet],
249
  ha='center', va='center',
250
- fontsize=24, fontweight='bold')
251
 
252
- # Configure plot appearance
253
  ax.set_xlim(-0.5, 3.5)
254
  ax.set_ylim(-0.5, 3.5)
255
  ax.set_aspect('equal')
256
  ax.axis('off')
257
- plt.tight_layout()
258
 
259
  return fig
260
 
261
  def chat_interface(query):
262
- """
263
- Main processing function for the Gradio interface.
264
- Args:
265
- query: User input string
266
- Returns:
267
- tuple: (text_response, image)
268
- """
269
  # Parse input
270
  dt, location, error = parse_query(query)
271
  if error:
@@ -286,7 +247,7 @@ def chat_interface(query):
286
  ZSizes = result["ZSizes"]
287
  longitudes = result["longitudes"]
288
 
289
- # Generate planet list text
290
  planet_list = "\n".join(
291
  f"{PLANET_RU[p]}: {lon_to_sign(longitudes[p])}"
292
  for p in PLadder
@@ -301,7 +262,7 @@ def chat_interface(query):
301
  # Generate coordinates text
302
  coords_text = format_coords(lat, lon)
303
 
304
- # Create visualization
305
  fig = plot_pladder(PLadder)
306
  buf = BytesIO()
307
  fig.savefig(buf, format='png', dpi=120, bbox_inches='tight')
 
9
  import pytz
10
  import swisseph as swe
11
 
12
+ # Initialize Swiss Ephemeris
13
+ swe.set_ephe_path(None)
14
 
15
  # Russian translations for planets
16
  PLANET_RU = {
17
+ 'Sun': 'Солнце', 'Moon': 'Луна', 'Mercury': 'Меркурий',
18
+ 'Venus': 'Венера', 'Mars': 'Марс',
19
+ 'Jupiter': 'Юпитер', 'Saturn': 'Сатурн'
20
  }
21
 
22
  # Planet symbols for plotting
 
32
  ]
33
 
34
  def parse_query(query):
35
+ """Parse the query into date, time, and location."""
 
 
 
 
 
 
36
  if not query.startswith("PLadder "):
37
  return None, None, "Query must start with 'PLadder'"
38
 
39
  try:
40
+ parts = query.split(maxsplit=3)
41
+ if len(parts) < 4:
42
+ return None, None, "Incomplete query (need date, time, and location)"
43
+
44
+ _, date_str, time_str, location = parts
45
  dt = parser.parse(f"{date_str} {time_str}")
46
  return dt, location, None
47
  except ValueError as e:
48
  return None, None, f"Invalid format: {str(e)}"
49
 
50
  def get_utc_time(dt, location):
51
+ """Convert local time to UTC using location's time zone."""
 
 
 
 
 
 
 
52
  geolocator = Nominatim(user_agent="pladder_app")
53
  try:
54
  loc = geolocator.geocode(location, timeout=10)
 
64
  local_dt = tz.localize(dt)
65
  utc_dt = local_dt.astimezone(pytz.UTC)
66
  return utc_dt, lat, lon, None
 
67
  except Exception as e:
68
+ return None, None, None, f"Error: {str(e)}"
69
 
70
  def format_coords(lat, lon):
71
+ """Format coordinates as degrees, minutes, seconds."""
 
 
 
 
 
 
 
72
  def dms(value, pos_dir, neg_dir):
73
  direction = pos_dir if value >= 0 else neg_dir
74
  abs_value = abs(value)
75
  degrees = int(abs_value)
76
  minutes = int((abs_value - degrees) * 60)
77
+ seconds = int(round(((abs_value - degrees) * 60 - minutes) * 60)
78
 
79
  # Handle rounding overflow
80
  if seconds >= 60:
 
91
  def lon_to_sign(lon_deg):
92
  """
93
  Convert ecliptic longitude to zodiac sign with position.
94
+ Now includes seconds in the output.
 
 
 
95
  """
96
  sign_idx = int(lon_deg // 30)
97
  degrees_in_sign = lon_deg % 30
98
  degrees = int(degrees_in_sign)
99
  minutes = int((degrees_in_sign - degrees) * 60)
100
+ seconds = int(round(((degrees_in_sign - degrees) * 60 - minutes) * 60)
101
 
102
+ # Handle rounding overflow
103
+ if seconds >= 60:
104
+ seconds -= 60
105
+ minutes += 1
106
  if minutes >= 60:
107
  minutes -= 60
108
  degrees += 1
109
 
110
+ return f"{ZODIAC_SIGNS[sign_idx]} {degrees}°{minutes:02}'{seconds:02}\""
111
 
112
  def PLadder_ZSizes(utc_dt, lat, lon):
113
+ """Calculate Planetary Ladder and Zone Sizes using Swiss Ephemeris."""
 
 
 
 
 
 
 
 
 
114
  if not -13000 <= utc_dt.year <= 17000:
115
  return {"error": "Date out of supported range (-13,000–17,000 CE)"}
116
 
 
121
  'Jupiter': swe.JUPITER, 'Saturn': swe.SATURN
122
  }
123
 
124
+ # Calculate Julian Day
125
  jd_utc = swe.julday(
126
  utc_dt.year, utc_dt.month, utc_dt.day,
127
  utc_dt.hour + utc_dt.minute/60 + utc_dt.second/3600
 
164
  else:
165
  X = 5
166
 
167
+ # Format size with seconds
168
  d = int(size)
169
  m = int((size - d) * 60)
170
  s = int(round(((size - d) * 60 - m) * 60))
 
191
  return {
192
  'PLadder': PLadder,
193
  'ZSizes': ZSizes,
194
+ 'longitudes': longitudes # Raw degrees for calculations
195
  }
196
 
197
  def plot_pladder(PLadder):
198
+ """Generate the original version of the planetary ladder visualization."""
199
+ fig, ax = plt.subplots(figsize=(6, 6))
 
 
 
 
 
 
200
 
201
+ # Draw the main triangle
202
  ax.plot([0, 1.5, 3, 0], [0, 3, 0, 0], 'k-', linewidth=2)
203
 
204
+ # Draw horizontal divisions (original style)
205
+ ax.plot([0.5, 2.5], [1, 1], 'k--')
206
+ ax.plot([1, 2], [2, 2], 'k--')
207
 
208
+ # Original planet symbol positions
209
  symbol_positions = [
210
+ (-0.2, 0.2), (0.3, 1.2), (0.8, 2.2),
211
  (1.5, 3.2), (2.2, 2.2), (2.7, 1.2), (3.2, 0.2)
212
  ]
213
 
 
215
  for (x, y), planet in zip(symbol_positions, PLadder):
216
  ax.text(x, y, PLANET_SYMBOLS[planet],
217
  ha='center', va='center',
218
+ fontsize=24)
219
 
220
+ # Configure plot appearance (original style)
221
  ax.set_xlim(-0.5, 3.5)
222
  ax.set_ylim(-0.5, 3.5)
223
  ax.set_aspect('equal')
224
  ax.axis('off')
 
225
 
226
  return fig
227
 
228
  def chat_interface(query):
229
+ """Process the user query and return text and plot."""
 
 
 
 
 
 
230
  # Parse input
231
  dt, location, error = parse_query(query)
232
  if error:
 
247
  ZSizes = result["ZSizes"]
248
  longitudes = result["longitudes"]
249
 
250
+ # Generate planet list text with full DMS
251
  planet_list = "\n".join(
252
  f"{PLANET_RU[p]}: {lon_to_sign(longitudes[p])}"
253
  for p in PLadder
 
262
  # Generate coordinates text
263
  coords_text = format_coords(lat, lon)
264
 
265
+ # Create visualization (original style)
266
  fig = plot_pladder(PLadder)
267
  buf = BytesIO()
268
  fig.savefig(buf, format='png', dpi=120, bbox_inches='tight')