묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결[왕초보편] 앱 8개를 만들면서 배우는 안드로이드 코틀린(Android Kotlin)
이미지 이름 오류
drawable 폴더에 splash 이미지 파일이 있는데 왜 이미지뷰에서 스플래쉬이미지가 적용이 안될까요?
-
미해결모두를 위한 딥러닝 - 기본적인 머신러닝과 딥러닝 강좌
파이썬 3.10 버전 tensor flow 설치 문의
텐서 플로우를 설치하려고 보니 파이썬 3.10 버전에 대해서는 내용이 없네요, 혹시 참고할 만한 사이트가 있을까요??
-
미해결반응형 웹사이트 포트폴리오(App Official Landing Website)
스타트업 CEO 커뮤니티 부분 위에 가 너무 붙어있습니다.
선생님 강의를 보고 잘 따라한 거같은데 선생님이 하신 화면과 제가 한 화면이 너무 다릅니다 스타트업 CEO 커뮤니티 위에 부분이 너무 붙어있습니다. 패딩 탑을 주어야 될까요? 아니면 마진탑을 주어야할까요? <!--section : feature--> <section class="feature"> <div class="feature-inner"> <div class="headline-share"> <h1>스타트업 CEO 커뮤니티</h1> <p> 스타트 업 비즈니스 발전을 위한 다양한 서비스를 제공합니다. </p> </div> <div class="feature-content"> <div class="feature-mokeup"> <img src="images/feature-mockup-01.png"> </div> <div class="feature-about"> <img src="images/icon-num-01.png"> <h2>스타트업 메이트 CEO 평생 회원 자격</h2> <p> 스타트업 메이트 회원가입은 평생 무료입니다. 조직의 리더 곧, CEO에게 필요한 경영, 전략, 조직관리 등 최신 경향을 안내하고 스타트업메이트 CEO에게 영감과 창의적인 아이디어를 만들 수 있도록 지원합니다. </p> </div> </div> <div class="feature-content"> <div class="feature-about"> <img src="images/icon-num-02.png"> <h2>CEO 오프라인 모임 참석(월 2회)</h2> <p> 스타트 업메이트 CEO 회원들만의 오프라인 모임을 월 2회 진행합니다. 온라인에서 부족한 상호작용을 위해 오프라인 모임을 만들고 해당 오프라인 모임에서 다야한 업종의 CEO들과 고민을 나누는 자리가 됩니다. </p> </div> <div class="feature-mokeup"> <img src="images/feature-mockup-02.png"> </div> </div> <div class="feature-content"> <div class="feature-mokeup"> <img src="images/feature-mockup-03.png"> </div> <div class="feature-about"> <img src="images/icon-num-03.png"> <h2>조직관리를 위한 오프라인 멘토링</h2> <p> 스타트업 메이트에서는 오프라인 멘토링을 정기적으로 개최합니다. 스타트업 메이트 CEO 회원이면 누구나 참석 가능합니다. 오프라인 멘토링에서는 명사를 초빙하여 경영혁신과 조직관리 그리고 최신 경영 트랜드에 대한 강연을 진행합니다. </p> </div> </div> </div> </section> /* ################## feature ##################### */ .feature-inner { width: 1300px; margin: auto; } .feature-content { overflow: hidden; margin: 100px 0; } .feature-content > div { float: left; width: 50%; text-align: center; } .feature-about { padding: 0 70px; padding-top: 80px; } .feature-about h2 { font-size: 30px; }
-
미해결애플 웹사이트 인터랙션 클론!
화면이 다 로드되지 않은 상태에서 스크롤을 내리면 오류창이 발생합니다
현재 28강을 수강하고 있습니다. 오류가 언제부터 발생했는지는 모르겠는데, 어디서 발생했는지 도무지 못찾겠습니다 ㅜㅜ 화면이 다 로드된 상태에서는 스크롤 창을 움직여도 오류코드가 뜨지 않는데, 화면이 아직 다 로드되지 않은 상태에서 스크롤을 움직이면 Uncaught TypeError: Cannot read properties of undefined (reading 'scrollHeight')라고 뜹니다 (() => { // 함수를 자동으로 호출하는 코드 // (function(){}) (); 동일 // 전역변수 사용을 최소화 하기 위해서 let yOffset = 0; //window.pageYOffset 대신에 사용할 변수 let prevScrollHeight = 0; //현재 스크롤 위치(yOffset)보다 이전에 위치한 scroll-section 들의 높이값의 합 let currentScene = 0; //현재 활성화된(눈앞에 보고 있는) scroll-section let enterNewScene = false; //새로운 scene가 시작되는 순간 true로 설정해줄 것임 const sceneInfo = [ { // 0 type: 'sticky', heightNum: 5, // 브라우저 높이의 5배로 scrollHeight 세팅 scrollHeight: 0, objs: { container: document.querySelector('#scroll-section-0'), messageA: document.querySelector('#scroll-section-0 .main-message.a'), messageB: document.querySelector('#scroll-section-0 .main-message.b'), messageC: document.querySelector('#scroll-section-0 .main-message.c'), messageD: document.querySelector('#scroll-section-0 .main-message.d'), canvas: document.querySelector('#video-canvas-0'), context: document.querySelector('#video-canvas-0').getContext('2d'), videoImages: [] }, values: { videoImagesCount: 300, imageSequence: [0, 299], canvas_opacity: [1, 0, { start: 0.9, end: 1 }], messageA_opacity_in: [0, 1, { start: 0.1, end: 0.2 }], messageB_opacity_in: [0, 1, { start: 0.3, end: 0.4 }], messageC_opacity_in: [0, 1, { start: 0.5, end: 0.6 }], messageD_opacity_in: [0, 1, { start: 0.7, end: 0.8 }], messageA_translateY_in: [20, 0, { start: 0.1, end: 0.2 }], messageB_translateY_in: [20, 0, { start: 0.3, end: 0.4 }], messageC_translateY_in: [20, 0, { start: 0.5, end: 0.6 }], messageD_translateY_in: [20, 0, { start: 0.7, end: 0.8 }], messageA_opacity_out: [1, 0, { start: 0.25, end: 0.3 }], messageB_opacity_out: [1, 0, { start: 0.45, end: 0.5 }], messageC_opacity_out: [1, 0, { start: 0.65, end: 0.7 }], messageD_opacity_out: [1, 0, { start: 0.85, end: 0.9 }], messageA_translateY_out: [0, -20, { start: 0.25, end: 0.3 }], messageB_translateY_out: [0, -20, { start: 0.45, end: 0.5 }], messageC_translateY_out: [0, -20, { start: 0.65, end: 0.7 }], messageD_translateY_out: [0, -20, { start: 0.85, end: 0.9 }] // translate의 %는 100%가 전체몸통 기준이다 //전체 scrollHeight을 1로 봤을 때, 0.1, 0.2, ...의 비율. 전체의 0.1의(10%) 구간을 0.3 ~ 0.4의 시점동안 실행한다 } }, { // 1 type: 'normal', // heightNum: 5, // type normal에서는 필요 없음 scrollHeight: 0, objs: { container: document.querySelector('#scroll-section-1'), content: document.querySelector('#scroll-section-1 .description') } }, { // 2 type: 'sticky', heightNum: 5, scrollHeight: 0, objs: { container: document.querySelector('#scroll-section-2'), messageA: document.querySelector('#scroll-section-2 .a'), messageB: document.querySelector('#scroll-section-2 .b'), messageC: document.querySelector('#scroll-section-2 .c'), pinB: document.querySelector('#scroll-section-2 .b .pin'), pinC: document.querySelector('#scroll-section-2 .c .pin'), canvas: document.querySelector('#video-canvas-1'), context: document.querySelector('#video-canvas-1').getContext('2d'), videoImages: [] }, values: { videoImagesCount: 960, imageSequence: [0, 959], canvas_opacity: [1, 0, { start: 0.9, end: 1 }], messageA_translateY_in: [20, 0, { start: 0.15, end: 0.2 }], messageB_translateY_in: [30, 0, { start: 0.5, end: 0.55 }], messageC_translateY_in: [30, 0, { start: 0.72, end: 0.77 }], messageA_opacity_in: [0, 1, { start: 0.15, end: 0.2 }], messageB_opacity_in: [0, 1, { start: 0.5, end: 0.55 }], messageC_opacity_in: [0, 1, { start: 0.72, end: 0.77 }], messageA_translateY_out: [0, -20, { start: 0.3, end: 0.35 }], messageB_translateY_out: [0, -20, { start: 0.58, end: 0.63 }], messageC_translateY_out: [0, -20, { start: 0.85, end: 0.9 }], messageA_opacity_out: [1, 0, { start: 0.3, end: 0.35 }], messageB_opacity_out: [1, 0, { start: 0.58, end: 0.63 }], messageC_opacity_out: [1, 0, { start: 0.85, end: 0.9 }], pinB_scaleY: [0.5, 1, { start: 0.5, end: 0.55 }], pinC_scaleY: [0.5, 1, { start: 0.72, end: 0.77 }], pinB_opacity_in: [0, 1, { start: 0.5, end: 0.55 }], pinC_opacity_in: [0, 1, { start: 0.72, end: 0.77 }], pinB_opacity_out: [1, 0, { start: 0.58, end: 0.63 }], pinC_opacity_out: [1, 0, { start: 0.85, end: 0.9 }] } }, { // 3 type: 'sticky', heightNum: 5, scrollHeight: 0, objs: { container: document.querySelector('#scroll-section-3'), canvasCaption: document.querySelector('.canvas-caption') }, values: { } } ]; function setCanvasImages(){ let imgElem; for (let i =0; i < sceneInfo[0].values.videoImagesCount; i++){ imgElem = document.createElement('img'); imgElem.src = `../video/sample1/IMG_${6726 + i}.JPG`; sceneInfo[0].objs.videoImages.push(imgElem); } let imgElem2; for (let i =0; i < sceneInfo[2].values.videoImagesCount; i++){ imgElem2 = document.createElement('img'); imgElem2.src = `../video/sample2/IMG_${7027 + i}.JPG`; sceneInfo[2].objs.videoImages.push(imgElem2); } } setCanvasImages(); function setLayout() { // 각 스크롤 섹션의 높이 세팅 for (let i = 0; i < sceneInfo.length; i++){ if(sceneInfo[i].type === 'sticky') { sceneInfo[i].scrollHeight = sceneInfo[i].heightNum * window.innerHeight; // 결과값을 scroll-section의 높이로 넣어줘야함 } else if(sceneInfo[i].type === 'normal') { sceneInfo[i].scrollHeight = sceneInfo[i].objs.container.offsetHeight; } sceneInfo[i].objs.container.style.height = `${sceneInfo[i].scrollHeight}px`; // 달러의 중괄호 내부에는 변수를 쓸 수 있다 } yOffset = window.pageYOffset; //처음 새로고침을 하고 아직 스크롤을 하지 않은 상태에서는 body에 show-scene-${currentScene}가 붙지않기 때문에 //load와 동시에 body에 show-scene-${currentScene}을 붙여주기 위한 코드 작업이 아래의 코드이다. //currentScene을 자동으로 세팅하는 코드 let totalScrollHeight = 0; for(let i = 0; i < sceneInfo.length; i++){ totalScrollHeight = totalScrollHeight + sceneInfo[i].scrollHeight; if(totalScrollHeight >= yOffset) { currentScene = i; break; } } document.body.setAttribute('id', `show-scene-${currentScene}`); const heightRatio = window.innerHeight / 1080; sceneInfo[0].objs.canvas.style.transform = `translate3d(-50%, -50%, 0) scale(${heightRatio})`; //각 디바이스(노트북, 스마트폰, 패드 등) 크기에 맞게 스케일을 조정해주는 코드 // 기존 높이(1080) 대비 줄어들거나 늘어난 디바이스의 높이(window.innerHeight)에 맞춰 이미지의 스케일을 조정해준다 sceneInfo[2].objs.canvas.style.transform = `translate3d(-50%, -50%, 0) scale(${heightRatio})`; } function scrollLoop(){ //몇번 째 scroll-section 이 눈앞에서 스크롤 중인지 판별하기 위한 함수 //scroll-section-0 + scroll-section-1 높이의 합보다 현재 스크롤의 YOffset의 크기가 클시 scroll-section-2가 시작됐다고 생각할 수 있다. enterNewScene = false; prevScrollHeight = 0; for (let i = 0; i < currentScene; i++){ prevScrollHeight = prevScrollHeight + sceneInfo[i].scrollHeight; } if (yOffset > prevScrollHeight + sceneInfo[currentScene].scrollHeight){ //여기에서 sceneInfo[currentScene]는 i와 동일한 역할을 해준다. enterNewScene = true; currentScene++; document.body.setAttribute('id', `show-scene-${currentScene}`); } if (yOffset < prevScrollHeight) { if (currentScene === 0){ return; } enterNewScene = true; currentScene--; document.body.setAttribute('id', `show-scene-${currentScene}`); } if (enterNewScene) return; //씬이 바뀌는 순간 true일 경우 함수를 종료함 playAnimation(); } function calcValues(values, currentYOffset){ // 배열에 넣어놓은 values 값 let rv; // 각 섹션 안에서 스크롤된 범위를 비율로 구하기 const scrollHeight = sceneInfo[currentScene].scrollHeight; const scrollRatio = currentYOffset/scrollHeight; // 전체범위에 초기값을 더해준다 (초기값 이후부터의 숫자가 필요해서) if(values.length === 3) { // start ~ end 사이의 애니메이션 실행 const partScrollStart = values[2].start * scrollHeight; const partScrollEnd = values[2].end * scrollHeight; const partScrollHeight = partScrollEnd - partScrollStart; if(currentYOffset >= partScrollStart && currentYOffset <= partScrollEnd){ rv = (currentYOffset-partScrollStart) / partScrollHeight * (values[1]- values[0]) + values[0]; } else if(currentYOffset < partScrollStart){ rv = values[0]; } else if(currentYOffset > partScrollEnd){ rv = values[1]; } } else { rv = scrollRatio * (values[1]- values[0]) + values[0]; } return rv; } function playAnimation() { const objs = sceneInfo[currentScene].objs; const values = sceneInfo[currentScene].values; const currentYOffset = yOffset - prevScrollHeight; const scrollHeight = sceneInfo[currentScene].scrollHeight; const scrollRatio = currentYOffset / scrollHeight; switch (currentScene) { case 0: // console.log('0 play'); let sequence = Math.round(calcValues(values.imageSequence, currentYOffset)); objs.context.drawImage(objs.videoImages[sequence],0,0); //sequence에 해당 객체가 선택이 되고, x y값이 0 0으로 배정된다 objs.canvas.style.opacity = calcValues(values.canvas_opacity, currentYOffset); if (scrollRatio <= 0.22) { // in objs.messageA.style.opacity = calcValues(values.messageA_opacity_in, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageA.style.opacity = calcValues(values.messageA_opacity_out, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_out, currentYOffset)}%, 0)`; } if (scrollRatio <= 0.42) { // in objs.messageB.style.opacity = calcValues(values.messageB_opacity_in, currentYOffset); objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageB.style.opacity = calcValues(values.messageB_opacity_out, currentYOffset); objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_out, currentYOffset)}%, 0)`; } if (scrollRatio <= 0.62) { // in objs.messageC.style.opacity = calcValues(values.messageC_opacity_in, currentYOffset); objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageC.style.opacity = calcValues(values.messageC_opacity_out, currentYOffset); objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_out, currentYOffset)}%, 0)`; } if (scrollRatio <= 0.82) { // in objs.messageD.style.opacity = calcValues(values.messageD_opacity_in, currentYOffset); objs.messageD.style.transform = `translate3d(0, ${calcValues(values.messageD_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageD.style.opacity = calcValues(values.messageD_opacity_out, currentYOffset); objs.messageD.style.transform = `translate3d(0, ${calcValues(values.messageD_translateY_out, currentYOffset)}%, 0)`; } break; case 2: // console.log('2 play'); let sequence2 = Math.round(calcValues(values.imageSequence, currentYOffset)); objs.context.drawImage(objs.videoImages[sequence2],0,0); if (scrollRatio <= 0.25) { // in objs.messageA.style.opacity = calcValues(values.messageA_opacity_in, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageA.style.opacity = calcValues(values.messageA_opacity_out, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_out, currentYOffset)}%, 0)`; } if (scrollRatio <= 0.57) { // in objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_in, currentYOffset)}%, 0)`; objs.messageB.style.opacity = calcValues(values.messageB_opacity_in, currentYOffset); objs.pinB.style.transform = `scaleY(${calcValues(values.pinB_scaleY, currentYOffset)})`; } else { // out objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_out, currentYOffset)}%, 0)`; objs.messageB.style.opacity = calcValues(values.messageB_opacity_out, currentYOffset); objs.pinB.style.transform = `scaleY(${calcValues(values.pinB_scaleY, currentYOffset)})`; } if (scrollRatio <= 0.83) { // in objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_in, currentYOffset)}%, 0)`; objs.messageC.style.opacity = calcValues(values.messageC_opacity_in, currentYOffset); objs.pinC.style.transform = `scaleY(${calcValues(values.pinC_scaleY, currentYOffset)})`; } else { // out objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_out, currentYOffset)}%, 0)`; objs.messageC.style.opacity = calcValues(values.messageC_opacity_out, currentYOffset); objs.pinC.style.transform = `scaleY(${calcValues(values.pinC_scaleY, currentYOffset)})`; } break; case 3: // console.log('3 play'); break; } } window.addEventListener('scroll',() => { yOffset = window.pageYOffset; scrollLoop(); }); window.addEventListener('load', function(){ setLayout(); sceneInfo[0].objs.context.drawImage(sceneInfo[0].objs.videoImages[0],0,0); }); // window.addEventListener('DOMContentLoaded', setLayout); 로 대체 할 수 있음. // DOMContentLoaded는 이미지 등은 제외하고 content 레이아웃만 로드되면 바로 실행됨. window.addEventListener('resize',setLayout); })();
-
미해결Slack 클론 코딩[실시간 채팅 with React]
회원가입하면 sleact체널을 기본으로 받잖아요
회원가입하면 그 회원가입한 계정에 들어가 있는 기본 sleact 체널에 이름을 백엔드 에서 어떤걸 수정해야 할가요?
-
미해결반응형 웹사이트 포트폴리오(App Official Landing Website)
header position: fixed 가 안됩니다.
안녕하세요 선생님 공부를 하다가 보니 헤더부분 gnb가 position: fixed; 가 안됩니다. header부분이 계속 따라오는 거 같아 말씀드려봤습니다. <!--Custom CSS & JS--> <link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="reset.css"> <link rel="stylesheet" href="reponsive.css"> <script src="js/costom.js"></script> </head> <body> <div class="container"> <!--##########Header##########--> <header> <div class="header-inner"> <div class="logo"> <a href="#none"><img src="images/logo.png"></a> </div> <div class="gnb"> <a href="#none">CEO 인사말</a> <a href="#none">서비스 특징</a> <a href="#none">자주 묻는 질문들</a> <a href="#none">경영비전</a> <a href="#none">사용자 리뷰</a> <a href="#none">앱 사용자 가이드</a> <a href="#none">최신소식</a> </div> </div> </header> /* ################## header ##################### */ header { position: fixed; width: 100%; z-index: 10; } .header-inner { width: 1300px; margin: auto; overflow: hidden; padding-top: 30px; padding-bottom: 15px; } .logo { float: left; } .logo img { margin-top: -7px; } .gnb { float: right; } .gnb a { margin: 10px; font-size: 16px; }
-
미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
프론트 세팅 관련 질문
제로초님 강의 잘 듣고 현업에서 잘 사용하고 있습니다!! 제가 이번에 채팅을 구현하게 될 거 같아서 제로초님이 제공하신 코드에서 프론트 코드만 세팅해서 테스트 해보고 싶은데 어떻게 하는 지 도통 읽어봐도 모르겠어서 글 남깁니다.프론트 코드 세팅하는 방법 알려주시면 감사하겠습니다!!
-
미해결[리뉴얼] Node.js 교과서 - 기본부터 프로젝트 실습까지
제로초님 회원 탈퇴 기능은 어떠한 방식으로 구성이 될까요 ?
회원 탈퇴 기능을 붙여 보고 싶은데 paranoid : true를 설정해서 soft delete를 해보고 싶은데 Model / user 시퀄라이저 쪽에서 회원 탈퇴의 경우 DB를 삭제하는 항목을 넣어줘야 되는건지 아니면 auth 라우터쪽에서 Post 형식으로 이메일 , 비밀번호를 입력하고 delete를 해야 되는지 감이 안 잡혀 여쭤봅니다 만약 라우터쪽에서 제거한다면 어떤 명령어로 DB를 제거할 수 있는지 알 수 있을까요 ??
-
미해결
Nextjs 배포 후에 캐시파일 생성이 가능한지 궁금합니다.
Nextjs 프로젝트를 배포했습니다. index.js에서 getServerSideProps()로 데이터를 가져와 next build 시에 index.html은 생성되지 않았습니다! Express로 next routing을 연결해 페이지가 보이도록 하고 있으며 pm2 로 무중단배포 중에 있습니다.! 메인 페이지에 접속했을 때 나타나는 페이지의 html 내용을 추출해 캐시파일로 생성하고 싶습니다. . Express로 구현이 가능할지 궁금합니다!
-
해결됨Slack 클론 코딩[실시간 채팅 with React]
loadable 에러 (라우터6버전)
안녕하세요, router6버전으로 업그레이드를 하고, 버전에 맞게 코드 수정을 했는데, loadable에서 저렇게 두개가 같은 에러가 납니다 다른분 질문하신거에는 'export default '가 없어서 났던거라고 되어있는데, 저는 그거는 다 되어있는데도 에러가 나네요.. 에러메세지는 사진에서처럼 나오는데 구글링해도 잘 나오지가 않아서 질문올립니다! 어떻게해야 해결이 될까요...
-
미해결홍정모의 따라하며 배우는 C++
moveTo함수 질문
안녕하세요. 비전공자라 매우 기초적인 질문일 수 있는데moveTo함수의 파라미터를 인티저 변수가 아닌 참조자 변수로 받는 것은 메모리를 줄이기 위함인가요?
-
미해결딥러닝 CNN 완벽 가이드 - TFKeras 버전
SGD 지그재그 질문드립니다.-2
안녕하세요 강사님 답변 감사드립니다. 댓글로 추가 질문 드렸는데 확인이 어려우신 것 같아 질문란에 올립니다. 그렇다면 교재의 그림(강의 11:43 쯤) X Y축은 가중치(여기에선 X Y 각각이 예를 들면 로스 함수를 이루는 w1, w2)이고 등고선 모양은 로스 함수의 loss값 분포라고 보면 되는지요
-
해결됨남박사의 파이썬으로 실전 웹사이트 만들기
회원가입 만들기 오류 문의 (AttributeError: 'Cursor' object has no attribute 'count') 오류
안녕하세요 몇일째 오류랑 씨름하다가 여기까지 왔는데.. 도저희 해결이 안나서 문의 남깁니다. 구글링이나.. 다른분들 오류 해결하시는거 찾아보면서 해도.. 계속오류 나면서 하니까 진도가 너무 늦네요..ㅠ 파이썬으로 실전 웹사이트 만들기 - 회원가입 페이지 만들기 중입니다. -오류내용- -코드- (run.py) from flask import Flask from flask import request from flask import render_template from flask_pymongo import PyMongo from bson.objectid import ObjectId from flask import abort from flask import redirect from flask import url_for from flask import flash import math import time from datetime import datetime app = Flask(__name__) app.config["MONGO_URI"] = "mongodb://localhost:27017/myweb" app.config["SECRET_KEY"] = "abcd" mongo = PyMongo(app) @app.template_filter('formatdatetime') def format_datetime(value): if value is None: return "" now_timestamp = time.time() offset = datetime.fromtimestamp( now_timestamp) - datetime.utcfromtimestamp(now_timestamp) value = datetime.fromtimestamp((int(value) / 1000)) + offset return value.strftime('%Y-%m-%d %H:%M:%S') @app.route("/list") def lists(): # 페이지 값 (값이 없는 경우 기본값는 1) page = request.args.get("page", 1, type=int) # 한페이지당 몇개의 게시물을 출력할지 limit = request.args.get("limit", 5, type=int) search = request.args.get("search", -1, type=int) keyword = request.args.get("keyword", type=str) # 최종적으로 완성된 쿼리를 만들 변수 query = {} # 검색어 상태를 추가할 리스트 변수 search_list = [] if search == 0: search_list.append({"title": {"$regex": keyword}}) elif search == 1: search_list.append({"contents": {"$regex": keyword}}) elif search == 2: search_list.append({"title": {"$regex": keyword}}) search_list.append({"contents": {"$regex": keyword}}) elif search == 3: search_list.append({"name": {"$regex": keyword}}) # 검색 대상이 한개라도 존재할 경우 query 변수에 $or 리스트를 쿼리 합니다. if len(search_list) > 0: query = {"$or": search_list} print(query) board = mongo.db.board datas = board.find({}).skip((page - 1) * limit).limit(limit) # 게시물의 총 갯수 tot_count = board.count_documents({}) # 마지막 페이지의 수를 구한다. last_page_num = math.ceil(tot_count / limit) # 페이지 블럭을 5개씩 표기 block_size = 5 # 현재 블럭의 위치 block_num = int((page - 1) / block_size) # 블럭의 시작 위치 block_start = int((block_size * block_num) + 1) # 블럭의 끝 위치 block_last = math.ceil(block_start + (block_size - 1)) return render_template("list.html", datas=list(datas), limit=limit, page=page, block_start=block_start, block_last=block_last, last_page_num=last_page_num, search=search, keyword=keyword) @ app.route("/view/<idx>") def board_view(idx): # idx = request.args.get("idx") if idx is not None: page = request.args.get("page") search = request.args.get("search") keyword = request.args.get("keyword") board = mongo.db.board data = board.find_one({"_id": ObjectId(idx)}) if data is not None: result = { "id": data.get("_id"), "name": data.get("name"), "title": data.get("title"), "contents": data.get("contents"), "pubdate": data.get("pubdate"), "view": data.get("view") } return render_template("view.html", result=result, page=page, search=search, keyword=keyword) return abort(404) @ app.route("/write", methods=["GET", "POST"]) def board_write(): if request.method == "POST": name = request.form.get("name") title = request.form.get("title") contents = request.form.get("contents") print(name, title, contents) current_utc_time = round(datetime.utcnow().timestamp() * 1000) board = mongo.db.board post = { "name": name, "title": title, "contents": contents, "pubdate": current_utc_time, "view": 0, } x = board.insert_one(post) print(x.inserted_id) return redirect(url_for("board_view", idx=x.inserted_id)) else: return render_template("write.html") @app.route("/join", methods=["GET", "POST"]) def member_join(): if request.method == "POST": name = request.form.get("name", type=str) email = request.form.get("email", type=str) pass1 = request.form.get("pass", type=str) pass2 = request.form.get("pass2", type=str) if name == "" or email == "" or pass1 == "" or pass2 == "": flash("입력되지 않은 값이 있습니다.") return render_template("join.html") if pass1 != pass2: flash("비밀번호가 일치하지 않습니다.") return render_template("join.html") members = mongo.db.members cnt = members.find({"email": email}).count() if cnt > 0: flash("중복된 이메일 주소입니다.") return render_template("join.html") current_utc_time = round(datetime.utcnow().timestamp(*1000)) post = { "name": name, "email": email, "pass": pass1, "joindate": current_utc_time, "logintime": " ", "logincount": 0 } members.insert_one(post) return "" else: return render_template("join.html") if __name__ == "__main__": app.run(host="0.0.0.0", debug=True, port=9000) (join.html) {% with messages = get_flashed_messages() %} {% if messages %} <script> alert('{{messages[-1]}}'); </script> {% endif %} {% endwith %} <table> <form name="form" action="/join" method="POST"> <thead> <caption>회원가입</caption> </thead> <tbody> <tr> <td>이름</td> <td><input type="text" name="name"></td> </tr> <tr> <td>이메일</td> <td><input type="text" nmae="email"></td> </tr> <tr> <td>비밀번호</td> <td><input type="password" name="pass"></td> </tr> <tr> <td>비밀번호 확인</td> <td><input type="password" name="pass2"></td> </tr> <tr> <td colspan="2"><input type="submit" value="가입하기"></td> </tr> </tbody> </form> </table>
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
console에서 날짜 부분의 글자가 깨져서 나옵니다
안녕하세요 강의를 수강하고있는 학생입니다. 다름이 아니라 Intellij console encoding이 어느부분이 문제인지, 다른 부분은 멀쩡하게 출력되는데 May 30, 2019 11 :56 PM 나머지로그들 ~~ 이런식으로 출력되야하는데 이런식으로 몇글자만 깨져서 나옵니다.. 인터넷에서 해결하라는대로 VM Setting에 encoding도 추가해봤고, Settiongs의 console > encoding도 utf-8로 바꿔보고 Maven을 다시 실행해봐도 해결되지 않아 문의남깁니다... 제가 뭔가 잘못하고있는걸까요,, 사실 별건 아니지만 나중에 실제 프로젝트를 진행할때 굉장히 거슬릴거같아서 미리 질문드립니다..!
-
미해결자바스크립트+jQuery 기초부터 실무까지 : 중급 Part.1
실습 - 노드 다루기 (4) - ex08 filter()와 find()
강사님의 설명 중 확인되어야 할 부분이 있어 의견을 남깁니다. //find()는 전체(혹은 기준 값 하위)에서만 검색을 하지만 filter()는 자기 자신의 //레벨에서 검색을 한다. 라고 설명 해주셨습니다만, 제가 예제를 통해 이해한 것은 아래와 같습니다. filter() 메서드 filter() 메서드로 어떤 요소를 찾으려면 복수 개의 jQuery객체를 가진 객체에서 사용해야 한다. 예시: ex09에서 <div id="samplePage"> ┬ div id="header" ├ div id="content" └ div id="footer" let $divGroup = $("div#samplePage div"); filter() 메서드는 $()함수를 통해 얻은 jQuery객체 배열(유사 배열)의 원소들 중에서 원하는 것을 찾을 수 있다.예시: $divGroup.filter("#header"); // → div id="header"를 찾는다. filter() 메서드는 $()함수를 통해 얻은 단일 jQuery객체에서 사용하면 형제 노드 중 검색조건에 맞는 노드가 있어도 객체가 반환되지 않는다.예시:let $divHeader = $("div#header");$divHeader.filter("#content"); // div id="content"에 해당하는 객체를 얻을 수 없다. filter() 메서드는 대상이 되는 jQuery객체 배열(유사 배열)의 원소들의 자식 또는 자손 요소는 찾지 않는다. find() 메서드 find() 메서드는 복수 개의 jQuery객체를 가진 jQuery배열(유사 배열)이나 단일 jQuery 객체에서 사용할 수 있다. find() 메서드는 자식, 자손 노드를 모두 탐색해 검색 조건에 맞는 노드를 반환한다. 위 메서드들의 성질을 볼 때 filter() 메서드는 어떤 노드를 찾기 보다는 복수 개의 결과에서 특정 요소를 선택하는 데 사용하는 것이 유용해 보입니다. find() 메서드는 filter() 보다 '검색' 처럼 사용할 수 있습니다. 정정되어야 할 내용이 있으면 다른 학우님들께 의견 부탁드립니다. 감사합니다.
-
미해결파이썬 동시성 프로그래밍 : 데이터 수집부터 웹 개발까지 (feat. FastAPI, async, await)
mongodb connection시 질문입니다.
안녕하세요 odmantic 관련해서 질문이 있는데요. client에서 따로 maxpoolsize나 minpoolsize 같은걸 안정하신 이유는 가벼운 프로젝트라서 일까요??
-
미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
queryRunner질문이요!
안녕하세요! 강의를 보고 공식문서도 봤다가 궁금한게 생겨서 여쭤봅니다! 강의에서 connection으로 하지 않고 예를 들어 this.workspaceMemberRepository로 한것은 처음 typorm에 연결했던 하나의 connection pool로만 연결된다고 하셨는데, 그럼 모든 repository들을 전부 connection 새로 열어서 마지막에 qurryRunner.release() 로 pool을 닫는게 더 좋은건가요...?
-
미해결실무에서 바로 쓰는 영어 이메일
강의자료 부탁드립니다
안녕하세요 강의 자료 메일로 공유 부탁드립니다. 감사합니다! yjoh29@naver.com
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
전체적인 이해 체크 좀 부탁드립니다.
안녕하세요. 이해에 몇 가지 막히는 점이 있어서 질문 드립니다. 1. 연관관계 매핑을 위해 List members를 만들었는데 TEAM 테이블의 컬럼에 추가되는 부분인가요? 2. TEAM_ID에 FK를 걸어줬는데 코드에서 어떤 부분에 해당하는 것 인가요? mappedBy = "team" mappedBy를 설정해 준 것이 fk를 설정한 것 인가요?.. Team 테이블에서 @GeneratedValue 를 통해 pk를 설정하고, Member 테이블에서 mappedBy로 Team team에 fk를 준 뒤 Team에서도 단방향으로 연관관계를 맺을 수 있게 List members를 생성해서 양방향 연관관계를 형성했고, 그 중심은 mappedBy로 fk를 설정해 준 Team team이다. 이렇게 이해하고 있는데 뭔가 한 부분이 빠진, 잘 못된 이해인 것 같아서 질문드립니다.
-
미해결자바스크립트+jQuery 기초부터 실무까지 : 중급 Part.1
실습 - 노드 다루기(3) ex05 中
소스코드 16번 줄에 //jQuery객체.textContent를 하게 되면 해당한는 값을 출력을 할 수 있다. 라고 강사님께서 적어주셨습니다만, textContent 속성은 jQuery객체가 아니고 JS DOM객체가 갖는 속성이 아닌지 궁금합니다. jQuery 객체의 텍스트 값은 $jQuery객체.text() 를 사용하는 것 같습니다.