본문 바로가기
토이프로젝트 - allt

23.05.16

by J1-H00N 2023. 5. 16.

전날 있었던 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)

'토이프로젝트 - allt' 카테고리의 다른 글

23.05.20  (0) 2023.05.20
23.05.19  (0) 2023.05.19
23.05.18  (0) 2023.05.18
23.05.17  (0) 2023.05.17
23.05.15  (0) 2023.05.15