전날 있었던 git강의에 대한 기록이 예상치 못한 사고로 전부 사라져 ppt를 보며 다시 기록하기로 했다.
git 명령어 모음
pwd : 현재 경로 확인
ls : 현재 경로의 모든 파일 조회
ls -al : 현재 경로의 모든 파일(숨김 폴더와 파일 포함) 조회
cd 경로 : 경로로 이동하기
cd.. : 상위 디렉터리로 이동하기
cd. : 현재 디렉터리로 이동하기
cd~ : 홈 티렉터리로 이동하기
touch 파일명 : 파일명으로 비어있는 파일 생성하기
cat 파일명 : 파일명의 내용 확인하기
vi 파일명 : 파일명의 파일 내용 편집하기
- a or i : 쓰기
- :w : 저장하기
- :q : 나가기
- :wq : 저장하고 나가기
rm 파일명 : 파일명 삭제하기
mkdir 디렉터리명 : 디렉터리 생성하기
rmdir 디렉터리명 : 비어있는 디렉터리 삭제하기
rm -rf 디렉터리명 : 비어있지 않은 디렉터리 삭제하기
git config --global user name "이름" : git에 이름 저장하기 (웬만하면 영어로)
git config --global user email "이메일" : git에 이메일 저장하기 (github에 등록된 이메일로)
git init : 로컬 저장소 만들기
git status : 작업 디렉터리 상태 확인하기
git add 스테이지에 추가할 대상 : 대상 스테이지에 올리기
git add . : 모든 변경사항 스테이지에 올리기
git commit : 자세한 커밋 메시지와 함께 커밋하기 (첫 번째 줄 제목 + 세 번째 줄부터 본문)
vi 처럼 편집가능, 본문 생략 가능
git commit -m '커밋 메시지' : 간단한 내용(제목)으로 커밋하기
git log : 커밋 목록 조회하기
git log --oneline : 커밋 목록 한줄로 정리해서 조회하기
git log -p : 커밋별 변경사항 목록 조회하기
git log --branches : 모든 브랜치의 커밋 목록 조회하기
git log --graph : 커밋 목록 그래프로 조회하기
git diff : 최근 커밋과 작업 디렉터리 비교하기
git diff --staged : 최근 커밋과 스테이지 비교하기
git diff 커밋1 커밋2 : 1에 비해 2의 변경점 비교하기
최초의 브랜치 이름 : master => 최근 github 등등에서 처음 브랜치 이름을 main으로 바꾸고 있다.
head : 현재 작업중인 브랜치의 커밋을 가리킨다. 일반적으로 현재 작업 중인 최신 커밋을 가리킨다.
checkout : head의 위치를 특정 브랜치의 최신 커밋으로 옮기는 것
merge : 서로 나뉜 브랜치를 병합하는 것
- 기존 브랜치에서 새로운 커밋 없이 새로운 브랜치의 커밋을 받아들이기만 하는 것을 빨리감기 병합이라고 한다.
- 기존 브랜치에서 새로운 커밋이 있는 상태에서 새로운 브랜치의 커밋을 추가로 병합하면 병합되는 커밋을 자동으로 생성하면서 병합이 진행된다.
git branch : 브랜치 목록 조회
git branch 브랜치 : 브랜치 생성하기
git branch -d 브랜치 : 브랜치 삭제하기
git checkout 브랜치 : 브랜치로 체크아웃하기
git checkout -b 브랜치 : 브랜치 생성하고 체크아웃하기
git merge 브랜치 : 브랜치 병합하기 (병합 후 브랜치는 체크아웃된 상태의 브랜치 기준, 병합된 브랜치가 삭제되진 않음)
병합과정에서 두 브랜치가 같은 내용을 다르게 커밋한 경우 충돌이 발생하는데,이때의 대처법은 아래와 같다.
1. 어떤 브랜치의 내용을 반영할지 직접 선별하고 나머지는 지운다.
2. 다시 커밋한다.
미니 프로젝트에서 개인 소개란을 수정
<style>
@import url('https://fonts.googleapis.com/css2?family=Gowun+Dodum&family=Nanum+Myeongjo&display=swap');
* {
font-family: 'Gowun Dodum', sans-serif;
}
body {
background-color: #c0bfbf;
}
/*로고 글씨체 및 위치 조정*/
.logo {
margin: 40px;
width: auto;
height: 100px;
color: black;
font-size: 40px;
font-weight: bold;
font-family: 'Gowun Dodum', sans-serif;
text-decoration: none;
}
.team-desc {
font-family: 'Gowun Dodum', sans-serif;
font-size: 35px;
text-decoration: none;
width: auto;
height: 200px;
padding: 10px;
margin-left: 20px;
}
.carousel {
width: 1000px;
height: 400px;
margin: auto;
margin-top: 80px;
}
/*이미지 크기 제한*/
.img-thumbnail {
width: 400px;
height: 400px;
}
/*하이퍼링크 효과 제거*/
a {
color: black;
text-decoration: none;
}
/*마우스 호버 시 밑줄 생성*/
a:hover {
color: #979595;
text-decoration: underline;
}
.private-desc {
font-size: 23px;
line-height: 2; /*줄 간격 조정*/
padding: 20px;
background-color: #c0f8d7;
width: 600px;
height: 400px;
border-radius: 10px;
border: 4px solid white
}
</style>
<div id="carouselExampleAutoplaying" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active" data-bs-interval="10000">
<div class="d-flex align-items-center">
<img src="https://ifh.cc/g/6os1V4.jpg" class="img-thumbnail">
<div class="private-desc">이름 : 김희열<br>mbti : ISTJ<br>장점 : 사람들의 필요와 요구에 따라 자신을 맞출 수 있습니다.<br>자신의 스타일 : 다른 사람이 원하지 않는다면 리더의 자리를 맡고, 잘못한 건 피드백 수용<br>블로그 주소 :<a href="https://ogig0818.tistory.com/">https://ogig0818.tistory.com/</a></div>
</div>
</div>
<div class="carousel-item" data-bs-interval="10000">
<div class="d-flex align-items-center">
<img src="https://ifh.cc/g/6Hp07q.jpg" class="img-thumbnail">
<div class="private-desc">이름 : 고은비<br>mbti : ISTJ<br>장점 : 고집이 세지 않고 다른 사람의 의견수용을 우선시합니다.<br>자신의 스타일 : 민폐는 되지 않기 위해 1인분 이상은 하자. 팀플은 세분화된 계획을 차근차근 진행하는 것을 선호<br>블로그 주소 : <a href="https://ggomcoding.tistory.com/">https://ggomcoding.tistory.com/</a></div>
</div>
</div>
<div class="carousel-item" data-bs-interval="10000">
<div class="d-flex align-items-center">
<img src="https://ifh.cc/g/2pn33O.jpg" class="img-thumbnail">
<div class="private-desc">이름 : 한지훈<br>mbti : ESTJ<br>장점 : 나이가 깡패다.<br>자신의 스타일 : 작업은 깔끔하고 보기 좋게 구성하는 것을 좋아합니다. 협업은 서로 좋은게 좋은것이라는 마인드<br>블로그 주소 : <a href="https://hjh-3229.tistory.com/">https://hjh-3229.tistory.com/</a></div>
</div>
</div>
<div class="carousel-item" data-bs-interval="10000">
<div class="d-flex align-items-center">
<img src="https://ifh.cc/g/JqxBl8.jpg" class="img-thumbnail">
<div class="private-desc">이름 : 송어진<br>mbti : ENTJ<br>장점 : 대화 가능한 사람이다. 힘든 일을 즐길 줄 안다.<br>자신의 스타일 : 팀플에 언제나 진심인 !열!쪙! 토론형 스타일<br>블로그 주소 : <a href="https://meitner.tistory.com/">https://meitner.tistory.com/</a></div>
</div>
</div>
<div class="carousel-item" data-bs-interval="10000">
<div class="d-flex align-items-center">
<img src="https://ifh.cc/g/J5SKL7.jpg" class="img-thumbnail">
<div class="private-desc">이름 : 송이삭<br>mbti : INTP<br>장점 : 화가 안남, 목표한 바가 있으면 집중력이 높음.<br>자신의 스타일 : 원하는 바가 있으면 주장하는 편이나 방향이 같은 팀원들의 좋은 의견이 있다면 그에 따라감<br>블로그 주소 : <a href="https://sisaac.tistory.com/">https://sisaac.tistory.com/</a></div>
</div>
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleAutoplaying" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselExampleAutoplaying" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
모든 데이터를 한꺼번에 처리할 함수를 넣을 제출 버튼을 추가
<button id="submit-button">제출</button>
#submit-button { /*css는 다른 버튼과 유사하게 만들기 위해 복사함*/
height: 50px;
width: 70px;
font-size: 20px;
border-radius: 5%;
border: none;
background-color: #ffffff;
color: #000000;
cursor: pointer;
margin: 10px;
margin-top: 50px;
}
데이터베이스에 기본값을 추가하고 각 mbti버튼을 누른 뒤 제출하면 해당 mbti만 카운트해서 증가하는 post 기능을 구현
from pymongo import MongoClient
from bson.objectid import ObjectId # update_one의 기능을 위해 import
client = MongoClient('mongodb+srv://sparta:test@cluster0.oid4wb8.mongodb.net/?retryWrites=true&w=majority')
database = client['dbsparta'] # 사용할 데이터 베이스 이름 지정
collection = database['mbti_data'] # 사용할 컬렉션 이름 지정
db = client.dbsparta
# 데이터베이스 값 초기화
mbti_values = {
'e' : 0,
'i' : 0,
'n' : 0,
's' : 0,
't' : 0,
'f' : 0,
'j' : 0,
'p' : 0
}
@app.route('/submit', methods=['POST'])
def submit():
# 클라이언트로부터 전송된 데이터를 받습니다.
mbti_data = request.get_json()
# mbti_data를 사용하여 mbti_values를 업데이트합니다.
# 각 mbti가 선택된 상태면 1, 아니면 0을 더하는 기능
for mbti_type, value in mbti_data.items():
mbti_values[mbti_type] += value
# 업데이트된 mbti_values를 데이터베이스에 저장하는 코드를 추가해야 합니다.
# update_one을 편하게 사용하기 위해 object_id를 사용
document_id = ObjectId('646361d2994e4ffc16c1cf03')
collection.update_one({'_id':document_id}, {'$set': mbti_values})
return jsonify({'msg': '저장완료'})
각 버튼에 javascript에서 불러오기 위한 아이디와 서버에서 사용할 data값 배정
<div class="mbti-vote">
<button id="e-btn" class="mbti-btn mbti-btn-left" data-mbti-type="e">E</button>
<p class="mbti-question mbti-question-left"> 왜 집에만 있어?</p>
<p class="mbti-divider"> vs. </p>
<p class="mbti-question mbti-question-right"> 왜 나가?</p>
<button id="i-btn" class="mbti-btn mbti-btn-right" data-mbti-type="i">I</button>
</div>
<div class="mbti-vote">
<button id="n-btn" class="mbti-btn mbti-btn-left" data-mbti-type="n">N</button>
<p class="mbti-question mbti-question-left">난 오늘도 꿈을 꾼다</p>
<p class="mbti-divider"> vs. </p>
<p class="mbti-question mbti-question-right"> 발 닦고 잠이나 자</p>
<button id="s-btn" class="mbti-btn mbti-btn-right" data-mbti-type="s">S</button>
</div>
<div class="mbti-vote">
<button id="t-btn" class="mbti-btn mbti-btn-left" data-mbti-type="t">T</button>
<p class="mbti-question mbti-question-left"> ...? </p>
<p class="mbti-divider"> vs. </p>
<p class="mbti-question mbti-question-right"> ㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜ</p>
<button id="f-btn" class="mbti-btn mbti-btn-right" data-mbti-type="f">F</button>
</div>
<div class="mbti-vote">
<button id="j-btn" class="mbti-btn mbti-btn-left" data-mbti-type="j">J</button>
<p class="mbti-question mbti-question-left"> 계획부터 짜자 </p>
<p class="mbti-divider"> vs. </p>
<p class="mbti-question mbti-question-right"> 내가 가는 곳이 곧 길이다 </p>
<button id="p-btn" class="mbti-btn mbti-btn-right" data-mbti-type="p">P</button>
</div>
각 버튼을 클릭했을 때 선택한 버튼은 배경 및 글자색이 바뀌고, 선택 상태 정보 저장
const eBtn = document.getElementById('e-btn');
const iBtn = document.getElementById('i-btn');
const nBtn = document.getElementById('n-btn');
const sBtn = document.getElementById('s-btn');
const tBtn = document.getElementById('t-btn');
const fBtn = document.getElementById('f-btn');
const jBtn = document.getElementById('j-btn');
const pBtn = document.getElementById('p-btn');
const mbtiBtns = [eBtn, iBtn, nBtn, sBtn, tBtn, fBtn, jBtn, pBtn];
// 대립되는 버튼 쌍을 배열로 정의합니다.
const conflictingPairs = [
[eBtn, iBtn],
[nBtn, sBtn],
[tBtn, fBtn],
[jBtn, pBtn]
];
// 버튼을 클릭했을 때의 동작을 설정합니다.
mbtiBtns.forEach(btn => {
btn.addEventListener('click', () => {
// 현재 버튼이 선택된 상태인지 확인
const isSelected = btn.classList.contains('selected');
// 대립되는 버튼들의 선택 상태를 초기화합니다.
conflictingPairs.forEach(pair => {
if (pair.includes(btn)) {
pair.forEach(conflictingBtn => {
conflictingBtn.classList.remove('selected');
});
}
});
// 선택된 버튼이 아니라면 선택 상태로 변경
if (!isSelected) {
btn.classList.add('selected');
}
});
});
또한 javascript코드가 DOM이 완전히 로드되기 전에 실행되면 요소를 찾지 못하거나 null을 반환하는 경우가 생겨 javascript를 body아래에 배치했다.
post 기능을 구현한 중간 완성 코드
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>올T 소개 페이지</title>
<!--bootstarp-->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4"
crossorigin="anonymous"></script>
<style>
/* 전체 body에 대한 스타일링 */
body {
font-family: Arial, sans-serif;
font-size: 16px;
line-height: 1.5;
color: #333;
background-color: #f8f8f8;
margin: 0;
padding: 0;
}
/* 팀 이름 헤더에 대한 스타일링 */
.team-title {
display: flex;
justify-content: space-between;
align-items: center;
background-color: #333;
color: #fff;
font-size: 24px;
font-weight: bold;
padding: 16px;
width: 100%;
}
/* 블로그 링크에 대한 스타일링 */
.myBlog a {
color: #333;
font-weight: bold;
text-decoration: none;
}
.myBlog a:hover {
color: blue;
text-decoration: underline;
}
/* MBTI 투표에 대한 스타일링 */
.mbti-vote {
display: flex;
align-items: center;
justify-content: center;
margin-top: 36px;
}
.mbti-vote button {
width: 80px;
height: 40px;
padding: 10px;
margin: 0 8px;
border: none;
background-color: #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
font-size: 16px;
font-weight: bold;
color: #333;
cursor: pointer;
}
.mbti-vote button:hover {
background-color: #333;
color: #fff;
}
.mbti-btn {
height: 50px;
width: 50px;
font-size: 20px;
border-radius: 50%;
border: none;
background-color: #ffffff;
color: #000000;
cursor: pointer;
margin: 10px;
}
.mbti-btn.selected {
background-color: #000;
color: #fff;
}
#submit-button {
height: 50px;
width: 70px;
font-size: 20px;
border-radius: 5%;
border: none;
background-color: #ffffff;
color: #000000;
cursor: pointer;
margin: 10px;
margin-top: 50px;
}
.mbti-btn-left {
position: absolute;
left: 0;
}
.mbti-btn-right {
position: absolute;
right: 0;
}
.mbti-question {
margin: 0 20px;
font-size: 18px;
}
.mbti-question-left {
position: absolute;
left: 25%;
}
.mbti-question-right {
position: absolute;
right: 25%;
}
.mbti-divider {
margin: 0;
font-size: 24px;
font-weight: bold;
position: absolute;
transform: translateX(-50%);
}
/* 슬라이드에 대한 스타일링 */
.team-desc {
font-family: 'Gowun Dodum', sans-serif;
font-size: 35px;
text-decoration: none;
width: auto;
height: 200px;
padding: 10px;
margin-left: 20px;
}
.carousel {
width: 800px;
height: 400px;
margin: auto;
margin-top: 100px;
}
.carousel-inner {
height: 400px;
}
.img-thumbnail {
width: 400px;
height: 400px;
object-fit: cover;
}
.myContent {
font-size: 20px;
padding: 20px;
background-color: #c0f8d7;
width: 65%;
height: 400px;
border-radius: 10px;
border: 3px solid black
}
</style>
</head>
<body>
<div class="team-title">
<p>팀 소개 페이지: 올T (All T)</p>
</div>
<div class="team-intro">
<div class="mbti-vote">
<button id="e-btn" class="mbti-btn mbti-btn-left" data-mbti-type="e">E</button>
<p class="mbti-question mbti-question-left"> 왜 집에만 있어?</p>
<p class="mbti-divider"> vs. </p>
<p class="mbti-question mbti-question-right"> 왜 나가?</p>
<button id="i-btn" class="mbti-btn mbti-btn-right" data-mbti-type="i">I</button>
</div>
<div class="mbti-vote">
<button id="n-btn" class="mbti-btn mbti-btn-left" data-mbti-type="n">N</button>
<p class="mbti-question mbti-question-left">난 오늘도 꿈을 꾼다</p>
<p class="mbti-divider"> vs. </p>
<p class="mbti-question mbti-question-right"> 발 닦고 잠이나 자</p>
<button id="s-btn" class="mbti-btn mbti-btn-right" data-mbti-type="s">S</button>
</div>
<div class="mbti-vote">
<button id="t-btn" class="mbti-btn mbti-btn-left" data-mbti-type="t">T</button>
<p class="mbti-question mbti-question-left"> ...? </p>
<p class="mbti-divider"> vs. </p>
<p class="mbti-question mbti-question-right"> ㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜ</p>
<button id="f-btn" class="mbti-btn mbti-btn-right" data-mbti-type="f">F</button>
</div>
<div class="mbti-vote">
<button id="j-btn" class="mbti-btn mbti-btn-left" data-mbti-type="j">J</button>
<p class="mbti-question mbti-question-left"> 계획부터 짜자 </p>
<p class="mbti-divider"> vs. </p>
<p class="mbti-question mbti-question-right"> 내가 가는 곳이 곧 길이다 </p>
<button id="p-btn" class="mbti-btn mbti-btn-right" data-mbti-type="p">P</button>
</div>
<button id="submit-button">제출</button>
</div>
<!--Autoplaying carousels-->
<div id="carouselExampleAutoplaying" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active" data-bs-interval="10000">
<div class="d-flex align-items-center">
<img src="https://ifh.cc/g/6os1V4.jpg" class="img-thumbnail">
<div class="myContent">
<p class="myName"><b>소개: </b>김희열</p>
<p class="myMBTI"><b>MBTI: </b>ISTJ</p>
<p class="myStr"><b>자신만의 강점: </b>사람들의 필요와 요구에 따라 자신을 맞출 수 있습니다.</p>
<p class="myStyle"><b>자신의 스타일: </b>다른 사람이 원하지 않으면 리더를 자청하고, 잘못한 건 피드백 받습니다</p>
<br>
<p class="myBlog"><b>블로그(Tistory): </b><a href=" https://ogig0818.tistory.com/">링크</a></p>
</div>
</div>
</div>
<div class="carousel-item" data-bs-interval="10000">
<div class="d-flex align-items-center">
<img src="https://ifh.cc/g/6Hp07q.jpg" class="img-thumbnail">
<div class="myContent">
<p class="myName"><b>소개: </b>고은비</p>
<p class="myMBTI"><b>MBTI: </b>ISTJ</p>
<p class="myStr"><b>자신만의 장점: </b>고집이 세지 않고 다른 사람의 의견수용을 우선시합니다.</p>
<p class="myStyle"><b>자신의 스타일: </b>민폐는 되지 않기 위해 1인분 이상은 하자. 팀플은 세분화된 계획을 차근차근 진행하는 것을 선호</p>
<br>
<p class="myBlog"><b>블로그(Tistory): </b><a href="https://ggomcoding.tistory.com/">링크</a></p>
</div>
</div>
</div>
<div class="carousel-item" data-bs-interval="10000">
<div class="d-flex align-items-center">
<img src="https://ifh.cc/g/t06QrT.jpg" class="img-thumbnail">
<div class="myContent">
<p class="myName"><b>소개: </b>한지훈</p>
<p class="myMBTI"><b>MBTI: </b>ESTJ</p>
<p class="myStr"><b>자신만의 장점: </b>나이가 깡패다.</p>
<p class="myStyle"><b>자신의 스타일: </b>작업은 깔끔하고 보기 좋게 구성하는 것을 좋아합니다. 협업은 서로 좋은게 좋은것이라는 마인드</p>
<br>
<p class="myBlog"><b>블로그(Tistory): </b><a href="https://ggomcoding.tistory.com/">링크</a></p>
</div>
</div>
</div>
<div class="carousel-item" data-bs-interval="10000">
<div class="d-flex align-items-center">
<img src="https://ifh.cc/g/JqxBl8.jpg" class="img-thumbnail">
<div class="myContent">
<p class="myName"><b>소개: </b>송어진</p>
<p class="myMBTI"><b>MBTI: </b>ENTJ</p>
<p class="myStr"><b>자신만의 장점: </b>대화 가능한 사람이다. 힘든 일을 즐길 줄 안다.</p>
<p class="myStyle"><b>자신의 스타일: </b>팀플에 언제나 진심인 !열!쪙! 토론형 스타일</p>
<br>
<p class="myBlog">
<b>노션(Notion): </b><a
href="https://lapis-holly-92a.notion.site/PROGRAMMING-7069dd8d9cff42a9bfa713aceb634adc">링크</a><br>
<b>블로그(Tistory): </b><a href="https://meitner.tistory.com/">링크</a>
</p>
</div>
</div>
</div>
<div class="carousel-item" data-bs-interval="10000">
<div class="d-flex align-items-center">
<img src="https://ifh.cc/g/J5SKL7.jpg" class="img-thumbnail">
<div class="myContent">
<p class="myName"><b>소개: </b>송이삭</p>
<p class="myMBTI"><b>MBTI: </b>INTP</p>
<p class="myStr"><b>자신만의 장점: </b>화가 안남, 목표한 바가 있으면 집중력이 높음.</p>
<p class="myStyle"><b>자신의 스타일: </b>원하는 바가 있으면 주장하는 편이나 방향이 같은 팀원들의 좋은 의견이 있다면 그에 따라감</p>
<br<<p class="myBlog">
<b>깃헙(GitHub): </b><a href="https://github.com/isaacsong-2">링크</a><br>
<b>블로그(Tistory): </b><a href="https://sisaac.tistory.com/">링크</a>
</p>
</div>
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleAutoplaying"
data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselExampleAutoplaying"
data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
</body>
<script>
const eBtn = document.getElementById('e-btn');
const iBtn = document.getElementById('i-btn');
const nBtn = document.getElementById('n-btn');
const sBtn = document.getElementById('s-btn');
const tBtn = document.getElementById('t-btn');
const fBtn = document.getElementById('f-btn');
const jBtn = document.getElementById('j-btn');
const pBtn = document.getElementById('p-btn');
const mbtiBtns = [eBtn, iBtn, nBtn, sBtn, tBtn, fBtn, jBtn, pBtn];
// 대립되는 버튼 쌍을 배열로 정의합니다.
const conflictingPairs = [
[eBtn, iBtn],
[nBtn, sBtn],
[tBtn, fBtn],
[jBtn, pBtn]
];
// 버튼을 클릭했을 때의 동작을 설정합니다.
mbtiBtns.forEach(btn => {
btn.addEventListener('click', () => {
// 현재 버튼이 선택된 상태인지 확인
const isSelected = btn.classList.contains('selected');
// 대립되는 버튼들의 선택 상태를 초기화합니다.
conflictingPairs.forEach(pair => {
if (pair.includes(btn)) {
pair.forEach(conflictingBtn => {
conflictingBtn.classList.remove('selected');
});
}
});
// 선택된 버튼이 아니라면 선택 상태로 변경
if (!isSelected) {
btn.classList.add('selected');
}
});
});
const submitButton = document.getElementById('submit-button');
submitButton.addEventListener('click', () => {
// 데이터베이스의 값을 업데이트합니다.
const mbtiValues = {};
mbtiBtns.forEach(button => {
const mbtiType = button.dataset.mbtiType;
mbtiValues[mbtiType] = button.classList.contains('selected') ? 1 : 0;
});
// mbtiValues 객체를 서버로 전송하는 코드를 추가해야 합니다.
fetch('/submit', { method: "POST", headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(mbtiValues) }).then((res) => res.json()).then((data) => {
alert(data['msg'])
window.location.reload();
})
.catch(error => {
console.log('데이터 전송 중에 오류가 발생했습니다:', error);
});
});
</script>
</html>
app.py
from flask import Flask, render_template, request, jsonify
app = Flask(__name__)
from pymongo import MongoClient
from bson.objectid import ObjectId
client = MongoClient('mongodb+srv://sparta:test@cluster0.oid4wb8.mongodb.net/?retryWrites=true&w=majority')
database = client['dbsparta']
collection = database['mbti_data']
db = client.dbsparta
@app.route('/')
def home():
return render_template('index.html')
# 데이터베이스 값 초기화
mbti_values = {
'e' : 0,
'i' : 0,
'n' : 0,
's' : 0,
't' : 0,
'f' : 0,
'j' : 0,
'p' : 0
}
@app.route('/submit', methods=['POST'])
def submit():
# 클라이언트로부터 전송된 데이터를 받습니다.
mbti_data = request.get_json()
# mbti_data를 사용하여 mbti_values를 업데이트합니다.
for mbti_type, value in mbti_data.items():
mbti_values[mbti_type] += value
# 업데이트된 mbti_values를 데이터베이스에 저장하는 코드를 추가해야 합니다.
document_id = ObjectId('646361d2994e4ffc16c1cf03')
collection.update_one({'_id':document_id}, {'$set': mbti_values})
return jsonify({'msg': '저장완료'})
if __name__ == '__main__':
app.run('0.0.0.0',port=5000,debug=True)