안녕하세요, 강사님. 강의의 수강 기한이 곧 만료되어 문의드립니다. 최근 1년간 다른 직종에 관련된 일을 하느라 강의를 거의 수강하지 못했습니다. 이번 연도에 강의를 들으며 빅데이터분석기사 실기를 준비하고 싶은데, 혹시 수강기한을 연장해 주실 수 없을까요? 제 메일은 ksforuo@gmail.com 입니다.
안녕하세요. 과제를 잘 못 이해한건가 싶기도 하지만 아래와 같은 조건하에 구현을 해 봤습니다. 수업 과정에서 Front-end는 고정인 상황이기 때문에 기존 API는 변경이 없다는 가정하에 변경 해 봤습니다. 시간대1개와 요일n개의 설정이 하나의 row로 묶여있는 상태로는 요일별 시간대 변동에 대응하기 까다로운 것 같아 요일별 개별 row로 저장하도록 일부 수정 하였습니다. API endpoint 모델 변경을 피하기 위해서 내부적으로 여러개의 요일별 row로 나누어 저장하도록 했습니다. 고민중에 작가님께서 올려 놓으신 레퍼런스 코드를 봤는데, 책에서 언급하신 것 처럼 postgres 경우와 sqlite 경우로 코드가 분기 되는 것을 보았고, 지금은 교육 과정이기 때문이라고 생각 하지만 배포 코드와 개발 환경 코드가 다른것은 여러모로 좋지 않은 것 같아 현재는 sqlite 기준으로 개별 DB구현에서만 지원하는 것은 배제하는 방향으로 구현 했습니다. 1과 같이 변경 함으로써, 기 등록된 정보의 수정에서는 개별 날짜 별 시간대 설정 면에서 자유도가 생겼다고 생각 됩니다. 타임슬롯의 변경과 삭제에 관해서는 내부적으로는 time-slot으로 관리하지만, 외부공개 id는 아니므로, 키 로서 start-time, end-time, weekday (API형태로서는 리스트)조합으로 정의 해서 동작 하도록 구현했습니다. 특히 삭제의 경우는 부득이 delete method의 경우는 payload가 포함되는것이 받아들여지지 않는 경우도 있는것을 고려해서, 새 등록 값 두가지(new_start_time과, new_end_time) 값이 모두 제공되고 같은 경우를 특정하여 삭제 동작으로 정의하여 동작하도록 구현했습니다. class TimeSlotUpdateByGroupIn(SQLModel): start_time: time end_time: time weekdays: Weekdays new_start_time: time | None = None new_end_time: time | None = None new_weekdays: Weekdays | None = None @model_validator(mode="after") def check_update_fields(self): update_fields = { "new_start_time": self.new_start_time, "new_end_time": self.new_end_time, "new_weekdays": self.new_weekdays, } if not any(value is not None for value in update_fields.values()): raise ValueError("최소 하나의 수정 필드는 반드시 제공되어야 합니다.") return self @router.post("/time-slots", status_code=status.HTTP_201_CREATED, response_model=TimeSlotOut) async def create_time_slot( user: CurrentUserDep, session: DbSessionDep, payload: TimeSlotCreateIn, ) -> TimeSlotOut: if not user.is_host: raise GuestPermissionError() weekdays = sorted(set(payload.weekdays)) # dup. check with already exist one stmt = select(TimeSlot).where( and_( TimeSlot.calendar_id == user.calendar.id, TimeSlot.weekday.in_(weekdays), TimeSlot.start_time < payload.end_time, TimeSlot.end_time > payload.start_time, ) ) result = await session.execute(stmt) existing_time_slot = result.scalars().first() if existing_time_slot: raise TimeSlotOverlapError() time_slots = [ TimeSlot( calendar_id=user.calendar.id, start_time=payload.start_time, end_time=payload.end_time, weekday=weekday, ) for weekday in weekdays ] session.add_all(time_slots) await session.commit() if not time_slots: raise TimeSlotOverlapError() return TimeSlotOut( start_time=time_slots[0].start_time, end_time=time_slots[0].end_time, weekdays=weekdays, created_at=time_slots[0].created_at, updated_at=time_slots[0].updated_at, ) @router.get( "/time-slots/{host_username}", status_code=status.HTTP_200_OK, response_model=list[TimeSlotOut], ) async def get_host_timeslots( host_username: str, session: DbSessionDep, ) -> list[TimeSlotOut]: stmt = ( select(User) .where(User.username == host_username) .where(User.is_host.is_(true())) ) result = await session.execute(stmt) host = result.scalar_one_or_none() if host is None or host.calendar is None: raise HostNotFoundError() stmt = select(TimeSlot).where(TimeSlot.calendar_id == host.calendar.id) result = await session.execute(stmt) time_slots = result.scalars().all() grouped: dict[tuple[time, time], TimeSlotOut] = {} for time_slot in time_slots: key = (time_slot.start_time, time_slot.end_time) if key not in grouped: grouped[key] = TimeSlotOut( start_time=time_slot.start_time, end_time=time_slot.end_time, weekdays=[time_slot.weekday], created_at=time_slot.created_at, updated_at=time_slot.updated_at, ) continue grouped[key].weekdays.append(time_slot.weekday) if time_slot.created_at < grouped[key].created_at: grouped[key].created_at = time_slot.created_at if time_slot.updated_at > grouped[key].updated_at: grouped[key].updated_at = time_slot.updated_at if not grouped: raise TimeSlotNotFoundError() for time_slot in grouped.values(): time_slot.weekdays = sorted(set(time_slot.weekdays)) return list(grouped.values()) @router.patch( "/time-slots", status_code=status.HTTP_200_OK, response_model=TimeSlotOut | None, ) async def update_time_slot( user: CurrentUserDep, session: DbSessionDep, payload: TimeSlotUpdateByGroupIn, ) -> TimeSlotOut | None: if not user.is_host: raise GuestPermissionError() current_weekdays = sorted(set(payload.weekdays)) stmt = select(TimeSlot).where( and_( TimeSlot.calendar_id == user.calendar.id, TimeSlot.start_time == payload.start_time, TimeSlot.end_time == payload.end_time, ) ) result = await session.execute(stmt) current_slots = result.scalars().all() if not current_slots: raise TimeSlotNotFoundError() existing_weekdays = sorted({slot.weekday for slot in current_slots}) if existing_weekdays != current_weekdays: raise TimeSlotNotFoundError() delete_only = ( payload.new_start_time is not None and payload.new_end_time is not None and payload.new_start_time == payload.new_end_time ) if delete_only: current_ids = [slot.id for slot in current_slots] await session.execute(delete(TimeSlot).where(TimeSlot.id.in_(current_ids))) await session.commit() return None new_start_time = payload.new_start_time or payload.start_time new_end_time = payload.new_end_time or payload.end_time new_weekdays = sorted(set(payload.new_weekdays or payload.weekdays)) if new_start_time >= new_end_time: raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_CONTENT, detail="시작 시간은 종료 시간보다 빨라야 합니다.", ) current_ids = [slot.id for slot in current_slots] stmt = select(TimeSlot).where( and_( TimeSlot.calendar_id == user.calendar.id, TimeSlot.weekday.in_(new_weekdays), TimeSlot.start_time < new_end_time, TimeSlot.end_time > new_start_time, TimeSlot.id.not_in(current_ids), ) ) result = await session.execute(stmt) existing_time_slot = result.scalars().first() if existing_time_slot: raise TimeSlotOverlapError() await session.execute(delete(TimeSlot).where(TimeSlot.id.in_(current_ids))) new_time_slots = [ TimeSlot( calendar_id=user.calendar.id, start_time=new_start_time, end_time=new_end_time, weekday=weekday, ) for weekday in new_weekdays ] session.add_all(new_time_slots) await session.commit() return TimeSlotOut( start_time=new_start_time, end_time=new_end_time, weekdays=new_weekdays, created_at=new_time_slots[0].created_at, updated_at=new_time_slots[0].updated_at, )
PPT - 11page 2장 max.jsx => main 아닌가요? ( 강의 영상이라..수정이.. 암튼 그러핟고요_ 예전에 제가 "코드로 배우는 스프링 웹 프로젝트" (개정판) ..ㅋㅋ 도서에도 오타 잡는 취미가 있었다는 ㅎㅎㅎ ^^ 다른 분이 찾으셨다면.. . .. 중복 Q&A 문의 죄송합니다.
안녕하세요 강의 잘보고 있습니다. 문의 내용이 있어서요 강의 내용중 소스내용이 많아 강사님 말씀처럼 자료에 있는 소스를 복붙하고 있는데요 문자 인코딩 (PPT와 vscode) 문제인지 복붙을 하고 보면 위와같이 붉은색으로 표시가 되는데 (일반 import를 안해서 생기는 line 말고요) 강의 화면을 보면 같은 증상으로 누구는 한글 에 노락 박스로 나타난다고 하는데 vt 및 저는 한글이 아니어도 같은 증상입니다. 라인 맨앞에 노락박스로 탭표시가 되는데 소스 가독에 상당히 힘들어서요. AI 말로는 위와같이 설정해도 같은 증상이고 저 내용에 "직접 삭제" ? ...ㅡㅡ (하나하나? 라인 마다?) 혹시 강의교안이나 다른데서 받아 올수 없나요? 아 git에서 다운로드 받을 수있는지요? (죄송합니다. 있으면 제가 아직 못찾은듯요..) 강사님... 급해결 요청드립니다. 아~ 너무 보기 힘드네요 ★ 앗! 지금 보니까 강사님 소스 작성할때는 잠깐 나타나따 사라지네요? 말씀드렸지만... 위 AI 내용데로 ..설정햇는데.. 구글링에도 같은소리만..ㅡㅡ; 저만 그런가요..?
안녕하세요 강의 잘보고 있습니다. 문의 내용이 있어서요 강의 내용중 소스내용이 많아 강사님 말씀처럼 자료에 있는 소스를 복붙하고 있는데요 문자 인코딩 (PPT와 vscode) 문제인지 복붙을 하고 보면 위와같이 붉은색으로 표시가 되는데 강의 화면을 보면 같은 증상으로 누구는 한글 에 노락 박스로 나타난다고 하는데 vt 및 저는 한글이 아니어도 같은 증상입니다. 라인 맨앞에 노락박스로 탭표시가 되는데 소스 가독에 상당히 힘들어서요. AI 말로는 위와같이 설정해도 같은 증상이고 저 내용에 "직접 삭제" ? ...ㅡㅡ (하나하나? 라인 마다?) 혹시 강의교안이나 다른데서 받아 올수 없나요? 아 git에서 다운로드 받을 수있는지요? (죄송합니다. 있으면 제가 아직 못찾은듯요..) 강사님... 급해결 요청드립니다. 아~ 너무 보기 힘드네요
안녕하세요. 좋은 강의 감사합니다. 강의를 듣다 몇가지 의문이 있어 글을 작성합니다. 애드몹 광고는 비공개 테스트시에도 적용을 해야하나요. 비공개 테스트시에도 애드몹광고를 추가한 상태에서 진행해야하나요? 비공개 테스트가 완료된 상태에서 애드몹광고를 추가하고 출시가 가능한가요? 비공개 테스트시에는 애드몸광고를 넣지않고 앱을 개시할때 추가해도되나요 애드몹 공고로 등록한 모바일 폰은 비공개 테스트 시 12개중한개의 모바일폰에 포함되나요.
안녕하세요 짐코딩님 덕분에 좋은 기능 배우고 있습니다! 일단 윈도우11서 claude code의 pro 이용을 하고 있습니다. 다름 아니라, 계획 검토 및 수정 요청 부분이 궁금해서 질문드립니다...! 저 같은 경우, 처음부터 interactive Question 기능이 나오는 것을 봤을 때, 이 기능이 default인 거 같더라고요 근데 계획을 다 보고, 계획 내용을 수정하고 싶은데, 따로 수정사항을 요청하는 선택지는 없고, esc를 누르면 아예 취소가 되서 미션 중의 3단계를 어떻게 할 수 있을지 궁금해서 질문드립니다!
저는 강사님의 refer & earn 주소로 runpod.io 사이트 열고, 영상에 나온 팝업창 누르고 구글 계정으로가입하고 10달러 결제까진 순조롭게 되었습니다....만 5달러는 안들어왔고 딱 결제한만큼 10달러만 있네요! 다른 분들은 어떻게... 추가로 5달러 받으셨는지 궁금합니다.
강의 수강 방법에 대해서 질문이 있습니다. 저는 Blind75를 순서대로 풀고 있는데 강의 순서랑은 Blind75 순서랑 조금 다르더라구요 자료구조 알고리즘을 모르는 상태로 강의를 시작해도 되는지 1번과 연계되는 질문으로 일단 문제 풀이를 시도하되 한 문제당 어느정도의 시간을 두고 풀면 되는지 보통 10분 정도 고민해보고 정말 모르겠다면 문제풀이 강의를 바로 들어보는 편입니다. Blind75 순서대로 문제를 풀면서 풀지 못한 문제에 대해서만 강의를 시청하면 되는지 좋은 강의 만들어주셔서 감사합니다.
안녕하세요. 좋은 강의 감사합니다. 강의를 듣다 보니 Storybook과 Chromatic이 컴포넌트 검증과 협업에 도움이 된다는 점은 이해할 수 있었습니다. 다만 한 가지 궁금한 점이 생겨 이렇게 메시지를 드립니다. 개인 프로젝트나 소규모 프로젝트에서도 Storybook을 사용하는 것이 적절한지, 아니면 디자인 시스템을 갖추거나 컴포넌트 재사용이 많은 프로젝트에서 주로 사용하는 도구인지 판단 기준이 궁금합니다. 규모, 협업 인원, 유지보수 관점에서 Storybook 도입 여부를 결정할 때 어떤 기준으로 판단하는 것이 좋은지도 알고 싶습니다. 모든 프로젝트에서 Storybook을 사용하는 것이 오히려 관리 비용이 될 수도 있겠다는 생각이 들어, Storybook을 사용하는 것이 효과적인 경우와 굳이 사용하지 않아도 되는 경우를 어떻게 구분하면 좋을지 조언을 듣고 싶습니다. 감사합니다.
'섹션 2. Next.js를 소개합니다' - '7. 1.3) 실습용 백엔드 서버 세팅하기' 강의 10:04 에서 npm i 하면 ' 30 vulnerabilities (9 low, 7 moderate, 13 high, 1 critical) '라고 취약점이 많이 떠서 AI를 활용해서 취약점을 제거 했습니다. AI가 권하는대로 npm audit fix npm install @nestjs/common@latest @nestjs/core@latest @nestjs/platform-express@latest @nestjs/swagger@latest @nestjs/cli@latest @nestjs/testing@latest 명령어를 사용하여 취약점을 제거했습니다. 이후 npm i 등 cmd 명령어를 순서대로 입력해서 해당 강의에서는 문제 없이 잘 진행이 됩니다. npm install @nestjs/XXX@latest 명령어들이 최신 버전을 설치하는거 같아서 나중에 버전 관련 문제가 생기지 않을까 걱정이 됩니다. 지금이라도 다시 백엔드 서버 세팅을 다시 맞춰서 강의와 맞는 버전으로 진행하는게 좋을까요?
안녕하세요 강의를 너무 잘 보고 있습니다. 강의를 보다가 문득 궁금한점이 있는데 프론트엔드 취업을 위해서 어느정도로 알고 있어야 되는지 그리고 어디까지 공부를 하고 회사를 지원을 해야되는지 궁금하더라구요. 뭔가 완벽히 그리고 많이 알야된다는 걱정에 지원을 못하고 계속 공부만 하게 되는거 같은데 조언 부탁드립니다
강의 내용 중에 "pip install pykrx" 이 부분에 대한 설명을 해 주신다고 했지만 나중에 VS CODE만 설명하시면서 실제로는 강의에서 빠져 있어서 기존 문의드린 오류가 난 게 아닌가 합니다. 느낌으로는 conda promp 상에서 실행하면 될 것 같은데 안되네요. "pip install pykrx" 를 어디에 설치해야 하나요? 아래 2곳에서는 안됩니다.