1+ import os
2+ import yaml
3+ import pandas as pd
4+ import math
5+ import time
6+
7+ # 설정
8+ FOLDER_PATH = "../_publications"
9+ TARGET_AUTHOR = "Kyunghwan Choi"
10+ METRICS_XLSX = "publications_metrics.xlsx"
11+ PLOT_PAPER_LIST = False
12+
13+ def is_empty (value ):
14+ """
15+ 값이 None, NaN, 혹은 빈 문자열인지 확인하는 함수
16+ """
17+ if value is None :
18+ return True
19+ if isinstance (value , float ) and math .isnan (value ):
20+ return True
21+ if str (value ).strip () == "" :
22+ return True
23+ return False
24+
25+ def load_metrics_from_xlsx (xlsx_path ):
26+ """
27+ Excel에서 {저널명: {IF, Quartile}} 정보를 가져옴
28+ """
29+ if not os .path .exists (xlsx_path ):
30+ print (f"[Warning] { xlsx_path } 파일이 없습니다. 엑셀 파일을 먼저 생성해주세요." )
31+ return {}
32+
33+ # 엑셀 파일 읽기
34+ df = pd .read_excel (xlsx_path )
35+
36+ # 저널 이름을 키로 하는 딕셔너리로 변환 (공백 제거)
37+ df ['Journal' ] = df ['Journal' ].astype (str ).str .strip ()
38+ metrics_map = df .set_index ('Journal' ).to_dict ('index' )
39+
40+ return metrics_map
41+
42+ def get_integrated_papers ():
43+ metrics_map = load_metrics_from_xlsx (METRICS_XLSX )
44+
45+ integrated_data = [] # 정보가 매칭된 논문들
46+ missing_journal_papers = [] # Excel에 정보가 없는 논문들
47+
48+ for root , _ , files in os .walk (FOLDER_PATH ):
49+ for file in files :
50+ # 1. '_'로 시작하는 참조 파일 및 확장자 예외처리
51+ if not file .endswith (".md" ) or file .startswith ("_" ):
52+ continue
53+
54+ file_path = os .path .join (root , file )
55+ try :
56+ with open (file_path , "r" , encoding = "utf-8" ) as f :
57+ content = f .read ()
58+
59+ parts = content .split ("---" )
60+ yaml_content = parts [1 ] if len (parts ) > 2 else content
61+ data = yaml .safe_load (yaml_content )
62+
63+ # 조건 필터링 (International Journal & Published & 본인 저자)
64+ is_int_journal = (data .get ("type" ) == "Journal Paper" and
65+ data .get ("domestic_or_international" ) == "International" )
66+
67+ has_author = any (isinstance (a , dict ) and a .get ("name" ) == TARGET_AUTHOR
68+ for a in data .get ("authors" , []))
69+
70+ if is_int_journal and has_author :
71+ pubs = data .get ("pub" , [])
72+ published_info = next ((p for p in pubs if p .get ("state" ) == "published" ), None )
73+
74+ if published_info :
75+ journal_name = published_info .get ("name" , "" ).strip ()
76+
77+ # 2. Excel 데이터 매칭
78+ if journal_name in metrics_map and (not is_empty (metrics_map [journal_name ].get ('Impact Factor' )) and not is_empty (metrics_map [journal_name ].get ('Quartile' ))):
79+ m = metrics_map [journal_name ]
80+ integrated_data .append ({
81+ "title" : data .get ("title" ),
82+ "journal" : journal_name ,
83+ "year" : published_info .get ("year" ),
84+ "impact_factor" : m .get ('Impact Factor' ),
85+ "quartile" : m .get ('Quartile' )
86+ })
87+ else :
88+ missing_journal_papers .append ({
89+ "title" : data .get ("title" ),
90+ "journal" : journal_name ,
91+ "year" : published_info .get ("year" )
92+ })
93+
94+ except Exception as e :
95+ print (f"[Error] { file_path } : { e } " )
96+
97+ return integrated_data , missing_journal_papers
98+
99+ # 실행
100+ papers_data , missing_data = get_integrated_papers ()
101+
102+ # 결과 출력 (Pandas DataFrame을 쓰면 출력이 예쁩니다)
103+ print ("\n === 논문 저널 매칭 결과 ===" )
104+ print (f"총 논문 수: { len (papers_data ) + len (missing_data )} " )
105+ print (f"매칭 완료된 논문 수: { len (papers_data )} " )
106+ print (f"정보가 없는 저널 논문 수: { len (missing_data )} " )
107+ recent_q1_papers = [p for p in papers_data if p ['quartile' ] == 'Q1' and int (p ['year' ]) >= int (time .strftime ('%Y' )) - 5 ]
108+ print (f"최근 5년 Q1 이상 논문 수: { len (recent_q1_papers )} " )
109+ recent_sci_papers = [p for p in papers_data if int (p ['year' ]) >= int (time .strftime ('%Y' )) - 5 ]
110+ print (f"최근 5년 SCI 논문 수: { len (recent_sci_papers )} " )
111+ print (f"최근 5년 Q1 이상 논문 비율: { len (recent_q1_papers ) / len (recent_sci_papers ) * 100 :.2f} %" )
112+
113+ if PLOT_PAPER_LIST :
114+ if papers_data :
115+ print ("\n ### [성공] 매칭 완료된 논문 목록 ###" )
116+ data = pd .DataFrame (papers_data )
117+ data .index = range (1 , len (data ) + 1 ) # 인덱스 1부터 시작
118+ print (data [['year' , 'journal' , 'impact_factor' , 'quartile' , 'title' ]])
119+
120+ if missing_data :
121+ print (f"\n ### [주의] Excel에 정보가 없는 저널 ({ len (missing_data )} 편) ###" )
122+ data = pd .DataFrame (missing_data )
123+ data .index = range (1 , len (data ) + 1 ) # 인덱스 1부터 시작
124+ print (data [['year' , 'journal' , 'title' ]])
125+
126+ print (f"\n ### 최근 5년간 Q1 이상 논문 ###" )
127+ if recent_q1_papers :
128+ data = pd .DataFrame (recent_q1_papers )
129+ data .index = range (1 , len (data ) + 1 ) # 인덱스 1부터 시작
130+ print (data [['year' , 'journal' , 'impact_factor' , 'quartile' , 'title' ]])
131+
132+ print (f"\n ### 최근 5년간 SCI 논문 ###" )
133+ if recent_sci_papers :
134+ data = pd .DataFrame (recent_sci_papers )
135+ data .index = range (1 , len (data ) + 1 ) # 인덱스 1부터 시작
136+ print (data [['year' , 'journal' , 'impact_factor' , 'quartile' , 'title' ]])
0 commit comments