Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
pingpingy1 authored Dec 1, 2023
2 parents d316495 + 2849556 commit 34a9573
Show file tree
Hide file tree
Showing 19 changed files with 562 additions and 240 deletions.
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# required environment variables
MONGO_CONNECTION_URI=mongodb://localhost:27017
OPEN_DATA_SERICE_KEY=some_key
OPEN_DATA_SERVICE_KEY=some_key
MONGO_DATABASE=council
3 changes: 3 additions & 0 deletions API/MongoDB.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class Councilor:
job: str
eduId: int
edu: str
year: str

@classmethod
def from_dict(cls, data: dict):
Expand All @@ -31,6 +32,7 @@ def from_dict(cls, data: dict):
job=data.get("job"),
eduId=int(data.get("eduId")),
edu=data.get("edu"),
year=data.get("year"),
)

def to_dict(self):
Expand All @@ -47,4 +49,5 @@ def to_dict(self):
"job": self.job,
"eduId": self.eduId,
"edu": self.edu,
"year": self.year,
}
3 changes: 2 additions & 1 deletion API/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@
"8": CouncilType.METROPOLITAN_COUNCIL,
"9": CouncilType.LOCAL_COUNCIL,
}

CANDIDATE_TYPECODE_TYPE = {
"2": CouncilType.NATIONAL_COUNCIL_CAND,
# "3": CouncilType.METRO_LEADER_CAND,
# "4": CouncilType.LOCAL_LEADER_CAND,
"5": CouncilType.METROPOLITAN_COUNCIL_CAND,
"6": CouncilType.LOCAL_COUNCIL_CAND,
"7": CouncilType.NATIONAL_COUNCIL_CAND,
"7": CouncilType.NATIONAL_COUNCIL_GLOBAL_CAND,
"8": CouncilType.METROPOLITAN_COUNCIL_CAND,
"9": CouncilType.LOCAL_COUNCIL_CAND,
}
42 changes: 25 additions & 17 deletions API/candidate.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,28 +68,36 @@ def fetch_all_data(
parser.add_argument(
"--drop-columns",
type=str,
default="num,huboid,hanjaName,status",
default="num,huboid,hanjaName,status,gihoSangse",
help="제거할 열 이름을 ','로 구분하여 입력하세요",
)
parser.add_argument(
"--save-method",
type=str,
# TODO: Add MongoDB support
# choices=["excel", "mongo"],
choices=["excel"],
default="excel",
help="데이터 저장 방식: 'excel' (현재는 excel만 지원)",
"-m", "--update-mongo", help="API 요청 결과를 MongoDB에 업데이트", action="store_true"
)
parser.add_argument(
"-o", "--output-store", help="API 요청 결과를 로컬에 저장", action="store_true"
)
parser.add_argument("--output-path", help="API 요청 결과 저장 경로", default="output")

args = vars(parser.parse_args())
print(args)
sgIds = args.get("sgIds").split(",")
if args.get("drop_columns"):
drop_columns = args.get("drop_columns").split(",")
else:
drop_columns = []
print(drop_columns)

data_list = fetch_all_data(
sgIds, args.get("sgTypecodes"), drop_columns=drop_columns
)

args = parser.parse_args()
sgIds = args.sgIds.split(",")
drop_columns = args.drop_columns.split(",") if args.drop_columns else []

data_list = fetch_all_data(sgIds, args.sgTypecodes, drop_columns=drop_columns)
for sgTypecode in args.sgTypecodes.split(","):
for sgTypecode in args.get("sgTypecodes").split(","):
if sgTypecode not in SG_TYPECODE:
raise ValueError(f"Invalid sgTypecode: {sgTypecode}")
if args.save_method == "excel":
save_to_excel(data_list, sgTypecode, is_elected=False)
elif args.save_method == "mongo":

if args.get("update_mongo"):
save_to_mongo(data_list, sgTypecode, CANDIDATE_TYPECODE_TYPE[sgTypecode])

if args.get("output_store"):
save_to_excel(data_list, sgTypecode, is_elected=False)
35 changes: 22 additions & 13 deletions API/elected.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ def fetch_data(
data_list = []
for item in root.findall(".//item"):
data_entry = {child.tag: child.text for child in item}
data_entry["year"] = sgId[:4]

for column in drop_columns:
data_entry.pop(column)
Expand Down Expand Up @@ -72,22 +73,30 @@ def fetch_all_data(
help="제거할 열 이름을 ','로 구분하여 입력하세요",
)
parser.add_argument(
"--save-method",
type=str,
choices=["excel", "mongo"],
default="excel",
help="데이터 저장 방식: 'excel', 'mongo'",
"-m", "--update-mongo", help="API 요청 결과를 MongoDB에 업데이트", action="store_true"
)
parser.add_argument(
"-o", "--output-store", help="API 요청 결과를 로컬에 저장", action="store_true"
)
parser.add_argument("--output-path", help="API 요청 결과 저장 경로", default="output")

args = parser.parse_args()
sgIds = args.sgIds.split(",")
drop_columns = args.drop_columns.split(",") if args.drop_columns else []
args = vars(parser.parse_args())
sgIds = args.get("sgIds").split(",")
if args.get("drop_columns"):
drop_columns = args.get("drop_columns").split(",")
else:
drop_columns = []

data_list = fetch_all_data(
sgIds, args.get("sgTypecodes"), drop_columns=drop_columns
)

data_list = fetch_all_data(sgIds, args.sgTypecodes, drop_columns=drop_columns)
for sgTypecode in args.sgTypecodes.split(","):
for sgTypecode in args.get("sgTypecodes").split(","):
if sgTypecode not in SG_TYPECODE:
raise ValueError(f"Invalid sgTypecode: {sgTypecode}")
if args.save_method == "excel":
save_to_excel(data_list, sgTypecode, is_elected=True)
elif args.save_method == "mongo":

if args.get("update_mongo"):
save_to_mongo(data_list, sgTypecode, ELECTED_TYPECODE_TYPE[sgTypecode])

if args.get("output_store"):
save_to_excel(data_list, sgTypecode, is_elected=True)
69 changes: 18 additions & 51 deletions API/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,18 @@ def save_to_mongo(data: List[dict], sgTypecode: str, where: str) -> None:
db = client["council"]
main_collection = db[where]

# TODO: Support other types of test
if sgTypecode in ["6", "9"]:
# TODO: Support other types of councils
if sgTypecode in ["8", "5", "2", "6", "9"]:
for entry in data:
if entry["wiwName"] == None:
print(entry)
entry["wiwName"] = change_local_name(entry["sdName"], entry["wiwName"])
district_id = get_district_id(entry["sdName"], entry["wiwName"])

if district_id:
main_collection.update_one(
{
"year": entry["year"],
"name": entry["name"],
"localId": district_id["localId"],
"metroId": district_id["metroId"],
Expand All @@ -60,34 +63,21 @@ def save_to_mongo(data: List[dict], sgTypecode: str, where: str) -> None:
print(
f"Warning: '{entry['sdName']} {entry['wiwName']}'에 해당하는 지역 ID가 존재하지 않습니다."
)
elif sgTypecode in ["5", "8"]:
main_collection = db["metro_councilor"]
elif sgTypecode in ["7"]:
for entry in data:
entry["wiwName"] = change_local_name(entry["sdName"], entry["wiwName"])
district_id = get_district_id(entry["sdName"], entry["wiwName"])

if not district_id:
print(
f"Warning: '{entry['sdName']} {entry['wiwName']}'에 해당하는 지역 ID가 존재하지 않습니다."
)
continue

if district_id:
main_collection.update_one(
{
"name": entry["name"],
"local_id": district_id["local_id"],
"metro_id": district_id["metro_id"],
},
{"$set": Councilor.from_dict(entry).to_dict()},
upsert=True,
)
else:
print(
f"Warning: '{entry['sdName']} {entry['wiwName']}'에 해당하는 지역 ID가 존재하지 않습니다."
)
entry["wiwName"] = "전국"
main_collection.update_one(
{
"year": entry["year"],
"name": entry["name"],
"localId": 0,
"metroId": 0,
},
{"$set": Councilor.from_dict(entry).to_dict()},
upsert=True,
)
else:
raise NotImplementedError("현재 구시군의회의원(6) 및 기초의원비례대표(9)만 구현되어 있습니다.")
raise NotImplementedError(f"아직 구현되지 않은 sgTypecode: {sgTypecode}")

print(f"데이터를 성공적으로 MongoDB '{main_collection.name}' 컬렉션에 저장하였습니다.")

Expand Down Expand Up @@ -124,29 +114,6 @@ def getLocalMetroMap() -> Dict[str, str]:
}


def getLocalMetroMap() -> Dict[str, str]:
db = client["district"]
result = db["local_district"].aggregate(
[
{
"$project": {
"localId": 1,
"metroId": 1,
"sdName": 1,
"wiwName": 1,
}
},
]
)
return {
(item["sdName"], item["wiwName"]): {
"local_id": item["localId"],
"metro_id": item["metroId"],
}
for item in result
}


def change_local_name(sdName, wiwName):
"""
1. 만약 '시' 와 '구'가 모두 wiwName에 있다면, '시' 까지만 쓰기
Expand Down
44 changes: 24 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# 다양성 평가 리포트 웹사이트 - 뉴웨이즈

<!-- # 깃헙은 최종일에 제출 필요!
- 팀별 GitHub repository 링크 및 발표 자료 Slack으로 제출
- GitHub 포함 사항
Expand All @@ -9,44 +10,47 @@
- 설치 및 실행 과정 설명
- 팀 및 팀원 소개
- (선택 사항) 데모 영상 -->

## 프로젝트 개요
프로젝트 이름 다양성 평가 리포트 웹사이트 - 뉴웨이즈
기간 23 가을-겨울

프로젝트 이름 다양성 평가 리포트 웹사이트 - 뉴웨이즈
기간 23 가을-겨울

## 설치 및 실행 과정

1. 파이썬 가상환경 생성
- 아래 명령을 실행하여 파이썬 가상환경을 생성합니다.
```bash
cd ~ && virtualenv newways --python=3.10
```
- 아래 명령을 실행하여 파이썬 가상환경을 생성합니다.
```bash
cd ~ && virtualenv newways --python=3.10
```
2. 가상환경 활성화
- 아래 명령을 실행하여 가상환경을 활성화합니다.
```bash
source ~/newways/bin/activate
```
- 아래 명령을 실행하여 가상환경을 활성화합니다.
```bash
source ~/newways/bin/activate
```
3. 레포지토리 클론
- 아래 명령을 실행하여 레포지토리를 클론합니다.
```bash
git clone https://github.com/NewWays-TechForImpactKAIST/main
```
```
4. 필요한 패키지 설치
- requirements.txt에 명시된 패키지를 설치합니다.
```bash
pip install -r requirements.txt
```
```
5. 환경 변수 설정
- `.env.example` 파일을 복사하여 `.env` 파일을 생성합니다.
```bash
cp .env.example .env
```
- `.env` 파일을 열어 환경 변수의 값을 필요에 따라 바꾸어줍니다.
```
- `.env` 파일을 열어 환경 변수의 값을 필요에 따라 바꾸어줍니다.
6. 예제 코드 실행
- 이 프로젝트는 여러 개의 파이썬 패키지로 구성되어 있습니다.
- 각각의 패키지는 독립적으로 실행할 수 있습니다. 단, 실행 시 python -m 옵션(module을 의미)을 사용해야 합니다.
- 크롤링 및 데이터베이스 저장 예제 코드를 실행하려면, 아래 명령을 실행합니다.
```bash
# scrap/local_councils/seoul/junggu.py 파일을 실행합니다.
python -m scrap.local_councils.seoul.junggu
# scrap/examples/database.py 파일을 실행합니다.
python -m scrap.examples.database
```
```bash
# scrap/local_councils/seoul/junggu.py 파일을 실행합니다.
python -m scrap.local_councils.seoul.junggu
# scrap/examples/database.py 파일을 실행합니다.
python -m scrap.examples.database
```
10 changes: 5 additions & 5 deletions analysis/age/hist_groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ def insert_data_to_mongo(
)


def cluster(df_original, n_clst, basedic):
def cluster(df_original, n_clst, basedic, clean_flag=True):
"""구역별 그룹을 만듭니다.
df_original: 데이터프레임
n_clst: 그룹 수
Expand All @@ -194,11 +194,11 @@ def cluster(df_original, n_clst, basedic):
histcoll = statdb["age_hist"]
statcoll = statdb["age_stat"] # method = "equal"에서 써 줄 통계.
# 기존 histogram 정보는 삭제 (나이별로 넣는 것이기 때문에 찌꺼기값 존재가능)
histcoll.delete_many(basedic.__dict__)
if basedic.method == "equal":
statcoll.delete_many(basedic.__dict__)
if clean_flag:
histcoll.delete_many(basedic.__dict__)
if basedic.method == "equal":
statcoll.delete_many(basedic.__dict__)
# 연도별로 데이터 찾아서 넣기!
df_original["year"] = df_original["sgId"] // 10000
df_original = df_original[df_original["year"].isin([2010, 2014, 2018, 2022])]
years = df_original["year"].unique()
for year in years:
Expand Down
Loading

0 comments on commit 34a9573

Please sign in to comment.