hossam 0.4.4__py3-none-any.whl → 0.4.6__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.
hossam/__init__.py CHANGED
@@ -6,7 +6,8 @@ from . import hs_prep
6
6
  from . import hs_stats
7
7
  from . import hs_timeserise
8
8
  from . import hs_util
9
- from .data_loader import load_data, load_info
9
+ from .hs_util import load_info
10
+ from .hs_util import _load_data_remote as load_data
10
11
 
11
12
  # py-modules
12
13
  import sys
hossam/hs_classroom.py CHANGED
@@ -15,10 +15,10 @@ from .hs_plot import config
15
15
  # 학생들을 관심사와 성적으로 균형잡힌 조로 편성한다
16
16
  # ===================================================================
17
17
  def cluster_students(
18
- df,
18
+ df: DataFrame | str,
19
19
  n_groups: int,
20
- score_cols: list = None,
21
- interest_col: str = None,
20
+ score_cols: list | None = None,
21
+ interest_col: str | None = None,
22
22
  max_iter: int = 200,
23
23
  score_metric: str = 'total'
24
24
  ) -> DataFrame:
@@ -173,7 +173,7 @@ def cluster_students(
173
173
  df_main,
174
174
  actual_n_groups,
175
175
  score_cols,
176
- interest_col,
176
+ interest_col, # type: ignore
177
177
  max_iter
178
178
  )
179
179
  else:
@@ -219,8 +219,8 @@ def cluster_students(
219
219
  def _balance_groups(
220
220
  df: DataFrame,
221
221
  n_groups: int,
222
- score_cols: list,
223
- interest_col: str = None,
222
+ score_cols: list | None = None,
223
+ interest_col: str | None = None,
224
224
  max_iter: int = 200
225
225
  ) -> DataFrame:
226
226
  """조 내 인원과 성적 균형을 조정하는 내부 함수.
@@ -281,7 +281,7 @@ def _balance_groups(
281
281
  count = grade_counts.loc[g, grade]
282
282
  min_g, max_g = grade_bounds[grade]
283
283
 
284
- if count <= max_g:
284
+ if count <= max_g: # type: ignore
285
285
  continue
286
286
 
287
287
  donors = group[group['성적그룹'] == grade]
@@ -291,12 +291,12 @@ def _balance_groups(
291
291
  if og == g:
292
292
  continue
293
293
  other_count = grade_counts.loc[og, grade]
294
- if other_count >= min_g:
294
+ if other_count >= min_g: # type: ignore
295
295
  continue
296
296
  other_group = df[df['조'] == og]
297
297
 
298
298
  og_interest = dominant_interest(other_group)
299
- need_groups.append((min_g - other_count, og, og_interest))
299
+ need_groups.append((min_g - other_count, og, og_interest)) # type: ignore
300
300
 
301
301
  need_groups.sort(reverse=True)
302
302
 
@@ -392,14 +392,14 @@ def _balance_group_sizes_only(
392
392
  # ===================================================================
393
393
  # 조 편성 결과의 인원, 관심사, 점수 분포를 시각화한다
394
394
  # ===================================================================
395
- def report_summary(df: DataFrame, interest_col: str = None, width: int = config.width, height: int = config.height, dpi: int = config.dpi) -> None:
395
+ def report_summary(df: DataFrame, interest_col: str | None = None, width: int = config.width, height: int = config.height, dpi: int = config.dpi) -> None:
396
396
  """조 편성 결과의 요약 통계를 시각화합니다.
397
397
 
398
398
  조별 인원 분포, 관심사 분포, 평균점수 분포를 나타냅니다.
399
399
 
400
400
  Args:
401
401
  df (DataFrame): cluster_students 함수의 반환 결과 데이터프레임.
402
- interest_col (str): 관심사 컬럼명
402
+ interest_col (str | None): 관심사 컬럼명
403
403
  width (int): 그래프 넓이. 기본값: config.width
404
404
  height (int): 그래프 높이. 기본값: config.height
405
405
  dpi (int): 그래프 해상도. 기본값: config.dpi
@@ -540,24 +540,24 @@ def report_summary(df: DataFrame, interest_col: str = None, width: int = config.
540
540
  plot_idx += 1
541
541
 
542
542
  # hs_plot.finalize_plot을 사용하여 마무리
543
- hs_plot.finalize_plot(axes, outparams=True, grid=False)
543
+ hs_plot.finalize_plot(axes, outparams=True, grid=False) # type: ignore
544
544
 
545
545
 
546
546
  # ===================================================================
547
547
  # 조별 점수 분포를 커널 밀도 추정(KDE) 그래프로 시각화한다
548
548
  # ===================================================================
549
- def report_kde(df: DataFrame, metric: str = 'average', width: int = config.width, height: int = config.height, dpi: int = config.dpi) -> None:
549
+ def report_kde(df: DataFrame | str, metric: str = 'average', width: int = config.width, height: int = config.height, dpi: int = config.dpi) -> None:
550
550
  """조별 점수 분포를 KDE(Kernel Density Estimation)로 시각화합니다.
551
551
 
552
552
  각 조의 점수 분포를 커널 밀도 추정으로 표시하고 평균 및 95% 신뢰구간을 나타냅니다.
553
553
 
554
554
  Args:
555
- df: cluster_students 함수의 반환 결과 데이터프레임.
556
- metric: 점수 기준 선택 ('total' 또는 'average').
555
+ df (DataFrame | str): cluster_students 함수의 반환 결과 데이터프레임.
556
+ metric (str): 점수 기준 선택 ('total' 또는 'average').
557
557
  'total'이면 총점, 'average'이면 평균점수. 기본값: 'average'
558
- width: 그래프 넓이. 기본값: config.width
559
- height: 그래프 높이. 기본값: config.height
560
- dpi: 그래프 해상도. 기본값: config.dpi
558
+ width (int): 그래프 넓이. 기본값: config.width
559
+ height (int): 그래프 높이. 기본값: config.height
560
+ dpi (int): 그래프 해상도. 기본값: config.dpi
561
561
 
562
562
  Examples:
563
563
  ```python
@@ -570,17 +570,17 @@ def report_kde(df: DataFrame, metric: str = 'average', width: int = config.width
570
570
  print("데이터프레임이 비어있습니다")
571
571
  return
572
572
 
573
- if '조' not in df.columns:
573
+ if '조' not in df.columns: # type: ignore
574
574
  print("데이터프레임에 '조' 컬럼이 없습니다")
575
575
  return
576
576
 
577
- has_score = '총점' in df.columns
578
- has_avg = '평균점수' in df.columns
577
+ has_score = '총점' in df.columns # type: ignore
578
+ has_avg = '평균점수' in df.columns # type: ignore
579
579
  if not has_score:
580
580
  print("점수 데이터가 없습니다")
581
581
  return
582
582
 
583
- labels = df['조'].unique().tolist()
583
+ labels = df['조'].unique().tolist() # type: ignore
584
584
  def _sort_key(v):
585
585
  try:
586
586
  return (0, int(v))
@@ -596,18 +596,18 @@ def report_kde(df: DataFrame, metric: str = 'average', width: int = config.width
596
596
 
597
597
  plot_idx = 0
598
598
  metric_col = '평균점수' if (metric or '').lower() == 'average' else '총점'
599
- if metric_col not in df.columns:
599
+ if metric_col not in df.columns: # type: ignore
600
600
  print(f"'{metric_col}' 컬럼이 없습니다")
601
601
  return
602
602
 
603
603
  for group in ordered_labels:
604
- group_df = df[df['조'] == group]
605
- group_series = group_df[metric_col].dropna()
604
+ group_df = df[df['조'] == group] # type: ignore
605
+ group_series = group_df[metric_col].dropna() # type: ignore
606
606
  n = group_series.size
607
607
  if n == 0:
608
608
  continue
609
609
 
610
- hs_plot.kde_confidence_interval(data=group_df, xnames=metric_col, ax=axes[plot_idx], callback=lambda ax: ax.set_title(f"{group}조"))
610
+ hs_plot.kde_confidence_interval(data=group_df, xnames=metric_col, ax=axes[plot_idx], callback=lambda ax: ax.set_title(f"{group}조")) # type: ignore
611
611
 
612
612
  plot_idx += 1
613
613
 
@@ -615,7 +615,7 @@ def report_kde(df: DataFrame, metric: str = 'average', width: int = config.width
615
615
  for idx in range(plot_idx, len(axes)):
616
616
  fig.delaxes(axes[idx])
617
617
 
618
- hs_plot.finalize_plot(axes)
618
+ hs_plot.finalize_plot(axes) # type: ignore
619
619
 
620
620
 
621
621
  # ===================================================================
@@ -690,10 +690,10 @@ def group_summary(df: DataFrame, name_col: str = '학생이름') -> DataFrame:
690
690
  # 학생 조 편성부터 시각화까지의 전체 분석 프로세스를 일괄 실행한다
691
691
  # ===================================================================
692
692
  def analyze_classroom(
693
- df,
693
+ df: DataFrame | str,
694
694
  n_groups: int,
695
- score_cols: list = None,
696
- interest_col: str = None,
695
+ score_cols: list | None = None,
696
+ interest_col: str | None = None,
697
697
  max_iter: int = 200,
698
698
  score_metric: str = 'average',
699
699
  name_col: str = '학생이름',
hossam/hs_gis.py CHANGED
@@ -22,10 +22,10 @@ def __geocode_item(session: requests.Session, index: int, addr: str, key: str) -
22
22
  """단일 주소를 VWorld API로 지오코딩합니다.
23
23
 
24
24
  Args:
25
- session: 재사용할 `requests.Session` 인스턴스.
26
- index: 입력 데이터의 인덱스(로그용).
27
- addr: 지오코딩할 도로명 주소 문자열.
28
- key: VWorld API 키.
25
+ session (requests.Session): 재사용할 `requests.Session` 인스턴스.
26
+ index (int): 입력 데이터의 인덱스(로그용).
27
+ addr (str): 지오코딩할 도로명 주소 문자열.
28
+ key (str): VWorld API 키.
29
29
 
30
30
  Returns:
31
31
  (latitude, longitude) 튜플.
@@ -90,12 +90,12 @@ def geocode(df: DataFrame, addr: str, key: str) -> DataFrame:
90
90
  """주소 컬럼을 일괄 지오코딩하여 위도/경도 컬럼을 추가합니다.
91
91
 
92
92
  Args:
93
- df: 입력 `DataFrame`.
94
- addr: 주소가 들어있는 컬럼명.
95
- key: VWorld API 키.
93
+ df (DataFrame): 입력 `DataFrame`.
94
+ addr (str): 주소가 들어있는 컬럼명.
95
+ key (str): VWorld API 키.
96
96
 
97
97
  Returns:
98
- 위도(`latitude`), 경도(`longitude`) 컬럼이 추가된 `DataFrame`.
98
+ DataFrame: 위도(`latitude`), 경도(`longitude`) 컬럼이 추가된 `DataFrame`.
99
99
 
100
100
  Raises:
101
101
  Exception: 지오코딩 과정에서 발생한 예외를 전파합니다.
@@ -164,11 +164,11 @@ def load_shape(path: str, info: bool = True) -> GeoDataFrame:
164
164
  """Shapefile을 읽어 `GeoDataFrame`으로 로드합니다.
165
165
 
166
166
  Args:
167
- path: 읽을 Shapefile(.shp) 경로.
168
- info: True면 데이터 프리뷰와 통계를 출력.
167
+ path (str): 읽을 Shapefile(.shp) 경로.
168
+ info (bool): True면 데이터 프리뷰와 통계를 출력.
169
169
 
170
170
  Returns:
171
- 로드된 `GeoDataFrame`.
171
+ GeoDataFrame: 로드된 `GeoDataFrame`.
172
172
 
173
173
  Raises:
174
174
  FileNotFoundError: 파일이 존재하지 않는 경우.
@@ -186,7 +186,7 @@ def load_shape(path: str, info: bool = True) -> GeoDataFrame:
186
186
 
187
187
  if info:
188
188
  print("\n✅ 테이블 정보")
189
- pretty_table(data.info(), tablefmt="pretty")
189
+ pretty_table(data.info(), tablefmt="pretty") # type: ignore
190
190
 
191
191
  print("\n✅ 상위 5개 행")
192
192
  pretty_table(data.head(), tablefmt="pretty")
@@ -226,12 +226,11 @@ def save_shape(
226
226
  - 확장자 없으면 .shp로 저장
227
227
 
228
228
  Args:
229
- gdf: 저장할 `GeoDataFrame` 또는 `DataFrame`.
230
- path: 저장 경로(.shp 또는 .gpkg, 확장자 없으면 .shp 자동 추가).
231
- crs: 좌표계 문자열(e.g., "EPSG:4326"). 미지정 시 WGS84.
232
- lat_col: DataFrame 입력 시 위도 컬럼명.
233
- lon_col: DataFrame 입력 시 경도 컬럼명.
234
-
229
+ gdf (GeoDataFrame | DataFrame): 저장할 `GeoDataFrame` 또는 `DataFrame`.
230
+ path (str): 저장 경로(.shp 또는 .gpkg, 확장자 없으면 .shp 자동 추가).
231
+ crs (str | None): 좌표계 문자열(e.g., "EPSG:4326"). 미지정 시 WGS84.
232
+ lat_col (str): DataFrame 입력 시 위도 컬럼명.
233
+ lon_col (str): DataFrame 입력 시 경도 컬럼명.
235
234
  Returns:
236
235
  None: 파일을 저장하고 반환값이 없습니다.
237
236