학습내용


조건부 렌더링

3가지 방법

  1. modalIsVisible ? () : null ⇒ 참이면 : 기준 왼쪽 콘텐츠 출력 거짓이면 오른쪽
  2. if 활용
  3. &&활용 : true일때만 콘텐츠 출력

 

cf. 프로퍼티 네임 지을때도 동작에 관련한 네이밍은 on을 붙이자.

폼 전송 기능 구현

  • 전송시 모달창 닫기
  • 입력된 두 값 가져오기
  • 목록에 포스트 추가 (동적으로 출력)

구현 순서

  1. 전송 기능 추가
    • onSubmit 속성으로 이벤트함수 수신하기
    • NewPost 컴포넌트에 있는 폼태그
    • submitHandler 만들기상태갱신을 사용해 유효성 검증 ⇒ 정규강의 듣기 )
    • (클라이언트 쪽 검증 코드 추가 및
    • preventDefault적용⇒ HTTP 요청을 보내버리니 페이지가 리로딩된다.
    • ⇒ 지금 우리는 프론트 작업만 하고 있으니까 이렇게 동작 안하도록!
    • 왜? 폼이 전송처리되면 submit이벤트가 트리거되어 브라우저는 자동으로 HTTP 요청을 서버에 보내버린다.
    1. ★ Post 목록 동적으로 추가하기
      • 부모에 있는 상태정의코드, 이벤트함수 NewPost 컴포넌트로 가져오기.
      • 추가하는 함수 만들기
        useState활용해서 상태배열에 추가해서 구현했지만, 이건 최적화된 코드가 아니다!
        ⇒ 새로운 상태가 이전 상태값을 바탕으로 한 것이라면, setPosts()에 애로우함수 넘겨줘야한다.
        ⇒ 왜??
        리액트 내부에서는 상태 업데이트 함수를 곧바로 실행하는게 아니다!
        업데이트가 서로 얽혀서 일어날때 이전 버전의 상태를 기반으로 잘못된 업데이트를 할 수 도 있다.
```jsx
// 폼 제출시 포스트 추가하는 함수
  const addPostHandler = (postData) => {
    setPosts((existingPosts) => [postData, ...existingPosts]);
    console.log(posts);
  };
```

- 리스트 렌더링시 key 프로퍼티가 필요한 이유

 컴포넌트에서 꼭 받아서 처리해야하는 프로퍼티가 아님, react가 제공하는 특수한 내장 프로퍼티이다.

학습내용

다음 그림의 키워드를 참고하여, 하나하나 뿌시도록 해야겠다.

 

바닐라 JS가 아닌 React를 사용하는 이유

React는 facebook에서 개발하였으며, 공식문서에 가보면 "사용자 인터페이스를 만들기 위한 Javascript 라이브러리"라고 한다.

  1. 선언형
    바닐라 js로 구현할 경우 거쳐야할 단계를 전부 작성해야한다.
    반면, React를 활용한다면 목표로 하는 UI만 정의만 하면 React가 알아서 단계를 수행한다.
    또한, 뷰만 설계하여 코드의 가독성과 유지보수성을 향상 시킨다.
    리액트 - 선언형
    바닐라js - 명령형
  2. 컴포넌트 기반 아키텍쳐
    코드의 모듈성과 재사용성 향상
  3. 가상 DOM 활용
    브라우저의 리플로우, 리페인트 과정을 최소화 할 수 있다!
    실시간으로 다수의 사용자가 이용하고 즉각 업데이트 해야하는 트위터나 증권앱을 예시로 들 수 있겠다.

cf. 리액트를 사용해야 하는이유

라이브러리 vs 프레임워크

  • 라이브러리
    특정 기능을 수행하는 도구 모음
    제어의 흐름이 전적으로 개발자에게 있다. 능동적으로 라이브러리를 호출하여 사용가능하다.
  • 프레임워크
    더 큰 구조적 패턴을 제공한다.
    제어의 역전 개념이 적용되어 프레임워크에 제어 흐름을 넘기고 틀 안에서 수동적으로 동작한다.

cf. 리액트를 프레임워크라 분류하는 사람들도 있던데??
=> 위에서 공식문서에 리액트는 라이브러리라고 나왔다고 했다.
하지만 프레임워크라 칭하는 사람들도 있어서 항상 궁금했던 차에 알아본 결과,
리액트 자체는 UI 를 만드는데 집중된 라이브러리이나, 여러가지 툴들과 결합하여 프레임워크처럼 활용할 수 있는 확장 가능성 때문에 때로는 경계가 모호하여 그런 것 같다.

JSX

jsx는 javascript에 XML을 추가하여 확장한 문법으로 공식적인 자바스크립트 문법은 아니라고 한다.

 

jsx를 사용하는 이유?
=> 자바스크립트 코드 안에서 UI 작업을 하면 더 간결하고 가독성 면에서도 좋다.

import './App.css';
import React from 'react';

function App() {
  return (
    <div>Hello World</div>
  );
}

export default App;

 

다른방식으로는

createElement를 사용하는 방식이 있는데 확실이 가독성 면에서 좋지는 않은 것 같다.

import './App.css';
import React from 'react';

function App() {
  return (
        React.createElement('div', null, 'Hello World')
  );
}

export default App;

Vite

jsx 문법 브라우저에서 사용 불가
⇒ 따라서 해당 문법을 브라우저에서 실행 가능한 코드로 변환해야함.
⇒ + 코드를 최적화 시키고(변수함수 이름 줄이고, 공백)
⇒ Vite와 같은 별도 도구를 사용하는 이유이다.

요즘 Vite가 많이 활용하는 핵심적인 이유??

번들링 과정 없이 ES 모듈을 직접 브라우저로 보내서 빠른 개발 환경 지원(이를 위해 HMR을 지원)
프로덕션 빌드에서는 Rollup이라는 번들러를 사용해서 빌드생성함. 즉, 빌드 도구의 역할도 수행

 

Webpack
Webpack은 여러 개의 모듈(html, css, js, image 등)을 하나의 javascript 파일로 묶어주는 모듈 번들러이다.
=> CRA(create-react-app)을 사용하면 내부적으로 웹팩을 사용하기 때문에 자동으로 구성이 된다.

Props

key와 value로 이루어진 객체형태이다.
리액트에서는 컴포넌트에 커스텀 속성을 props라는 이름으로 추가하게 해준다.

상위 컴포넌트에서 하위 컴포넌트를 호출할 때

import Post from "./Post";

const PostList = () => {
    return <Post name='bae' />; 
};

이렇게 하위 컴포넌트로 props를 전달할 수 있다. (React 특성 - 단방향 데이터 흐름)
하지만, 이렇게만 끝내버리면 리액트 입장에서는 name 속성을 어디에 뿌려야할지 알 수가 없다. 리액트에게 해당 속성을 어떻게 처리할지도 알려줘야 한다.

즉, 호출되는 대상 컴포넌트(자식컴포넌트)에도 Props 인자를 설정해야한다.

const Post = (props) => {
  return (
    <li className={classes.post}>
      <p className={classes.author}>{props.author}</p>
      <p className={classes.text}>{props.body}</p>
    </li>
  );
};

핵심

  1. 부모컴포넌트에서 자식컴포넌트로만 props 전달이 가능
    • 리액트 특성인 단방향 데이터 흐름
  2. 자식컴포넌트는 props 인자를 활용하여 부모컴포넌트에 접근
  3. 자식 컴포넌트는 props를 직접 수정할 수 없으며, 오로지 읽기만 가능

CSS 모듈

CRA나 vite로 생성한 프로젝트에서 제공되는 기능이다.
html, jsx에서 활용하는 클래스 이름이 자동으로 고유한 클래스 이름으로 변환됨. => 이름 충돌이 나지 않는 장점이 있다!

import시에 .module을 붙이면 CSS모듈을 활용하겠다고 vite나 cra에 알리는 것임. (아래 import문 참고)

import classes from ‘./Post.module.css';

⇒ 이렇게하면 나중에 css 클래스 이름이 고유한 이름으로 변환된다.

classes라는 것은 객체가 되고, 해당 css파일에 정의해둔 클래스들은 이 객체의 프로퍼티 네임이 된다.

useState

컴포넌트 내에서 변수 값을 변경해도, 리액트는 변경사실을 감지하지 못한다.
왜???
=> 일반 변수는 React 상태관리 시스템 외부에 있다. 따라서 컴포넌트의 한 렌더링 사이클 내에서만 존재한다.

★ 리액트의 상태관리와 렌더링 프로세스

  1. 초기 렌더링
    처음 마운트 시, JSX 코드를 실행하여 UI 렌더링한다.
  2. 상태 변경
    useState()에서 반환된 setter함수가 호출되면 상태가 업데이트 된다.
    => 리액트가 이를 감지한다.
  3. 컴포넌트 리렌더링
    상태가 변경되면 해당 컴포넌트의 렌더링 함수가 다시 실행되어 새로운 UI가 생성된다.
  4. 화면 업데이트
    기존 UI와 비교하여 실제 DOM을 최소한으로 업데이트한다. => 성능면에서 중요

상태 올리기

=> 이부분이 조금 어려웠던 부분인 것 같아서 내일 다시 추가로 학습을 해봐야겠다.

해당 폼을 모달창으로 만들기
다음 두가지 방법중 모달 컴포넌트로 구현하는 것을 실습해봤다.

  1. CSS 구현
    NewPost 컴포넌트에 적용된 폼스타일을 모달처럼 보이도록 변경
  2. 모달 컴포넌트를 별도로 구현
    안에 있는 여러 콘텐츠를 오버레이 스타일로 만들기.
    => 복잡한 형태의 웹사이트에서 이 방법이 좋다고 한다.

전달받은 props를 통해 속성에 접근할 때,

const Post = (props) => {
  return (
    <li className={classes.post}>
      <p className={classes.author}>{props.author}</p>
      <p className={classes.text}>{props.body}</p>
    </li>
  );
};

=> 이렇게 사용할 수도 있지만, ‘props.’ 를 굳이 사용할 필요없이

 

const Modal = ({ children }) => {
  return (
    <>
      <div className={classes.backdrop} />
      <dialog open className={classes.modal}>
        {children}
      </dialog>
    </>
  );
};

_객체구조분해_를 사용해 특정 속성에 바로 접근이 가능하다.
children 프로퍼티가 참조하는것은
사용자 정의 컴포넌트의 본문 태그안에 담겨 전달되는 콘텐츠이다!

cf. dialog 태그와 open속성.

open속성의 기본값은 true이고, 이게 있어야 다이얼로그 요소가 자동으로 화면에 표시된다.

children 속성을 사용하는 이유

다른 컴포넌트를 래핑할 수 있는 래퍼 컴포넌트를 만들어 사용할수있다.

 

멘토링


Q) React에서 컴포넌트를 스타일링 하는 여러가지 방법들에는
CSS모듈, styled-components, emotion, 기타 프레임워크(부트스트랩, tailwind, sass)등이 있다고 알고 있습니다.
각각의 장단점이 있겠지만, 유지보수나 클린코드 면에서 멘토님의 취향을 반영한 의견이 궁금합니다!

A) CSS를 작업할때는 개인적으로 조금 내려놓는 편이긴 하다.
HTML이나, 컴포넌트 작성에 조금더 유지보수면에서 신경을 쓰는편이고,

그래도 emotion이 여러가지 타협점을 찾거나 하기에는 좋았던 것 같다.라고 하셨던 것 같다.
아마 emotion이 컴포넌트의 재사용성을 높이면서도 스타일링의 유연성을 유지할 수 있다는 말씀이신 건가 싶다?!

학습내용


연산자 우선순위

1.()
2.단항 연산자(--, ++, !)
3.산술 연산자(+, -, *, /, %)
4.비교 연산자(>, >=, <, <=, ==, ===, !==, !=)
5.논리 연산자(&&, ||)
6.대입(복합 대입)연산자(=, +=, -=, *=, /=, %=)

console.log(5 !< 5) // syntax error
console.log(!5 < 5) // false
console.log(!(5 < 5)) // true

반복문

for ... of - 반복가능한 대상

for ... of가 적용되는 대상이 더 적다고 알아두면 될것같다.

cf. 대괄호 표기법

const loggedInUser = {
name: 'Max',
age: 32,
isAdmin: true
};

for (const propertyName in loggedInUser) {
console.log(propertyName);  // 순차적으로 프로퍼티 name 출력
console.log(loggedInUser[propertyName]);   // 순차적으로 프로퍼티 value출력

// loggedInUser.propertyName 으로 하면 안됨.(저장된 이름이 없어서)
// 하지만 대괄호 표기법으로 하면 값에 동적으로 엑세스 할 수 있다.
}

유사배열 객체

자바스크립트에서의 배열은 일반적인 배열과는 다르다.
일반 배열의 동작을 흉내낸 유사배열 객체라고 할 수 있다.

=> console.log를 찍어보면 알 수 있듯이, 인덱스를 프로퍼티 키로 갖으며 length 프로퍼티를 갖는 특수한 객체이다

유사배열은 배열에 내장되어 있는 함수들을 사용할 수 없다.
이런 기능을 사용하기 위해서는 call, apply, bind 등을 사용한다.

call, apply는 다른 객체에 내장된 함수를 사용할 수 있게 해준다.

bind는 call,apply와는 달리 실행은 하지 않고 가리키는 this만 바꾼다.

cf. 유사배열을 사용해야하는 이유?

프로토타입 기반 언어

자바스크립트가 객체를 생성하는 방법이다.
JS에서 모든 객체는 상속 개념에 따라 자신의 부모 역할을 하는 객체와 연결되어 있는데, 이런 부모 객체를 프로토타입 객체라고 한다.

Java, C++와 같은 클래스 기반 객체지향 언어와 달리,
JS는 프로토타입 기반 객체지향 언어이다.

클래스 기반 객체지향 언어는 객체 생성을 위해 클래스 정의가 선행되어야 하지만,
프로토타입 언어는 클래스 없이 객체 생성이 가능하다.

객체 생성 방법

(1) 객체 리터럴
편한 방법이지만, 동일한 프로퍼티 구조를 갖는 객체를 여러개 생성해야 할 경우에는 비효율적.
e.g. 복수의 사용자, 메뉴 내 다양한 아이템을 객체로 표현할 경우

(2) 생성자 함수활용
생성자 함수를 활용해 객체를 생성하면 프로퍼티 구조가 동일한 여러개의 객체 동시 생성하기 용이.

프로퍼티

(1) 객체 프로퍼티 값 접근 방법

  1. 마침표 표기법
  2. 대괄호 표기법
    객체에 존재하지 않는 프로퍼티를 참조하면 undefined를 반환한다.

(2) 프로퍼티 동적 생성
객체가 소유하고 있지 않은 프로퍼티 키에 값을 할당해도 생성해줌.

학습내용


전역객체

DOM

DOM(Document Object Model)이란??
=> ★ JS를 통해 쿼리하거나 조작하기 위해 파싱된 HTML 및 CSS 콘텐츠의 표현

브라우저는 웹사이트를 불러오면 HTML 코드를 분석한다. (파싱)
모든 HTML element를, 자바스크립트 객체 묶음으로 해석해준다.

DOM이 필요한 이유

⇒ DOM을 통해 js코드는 화면에 표시되는 내용을 쿼리 및 조작하여 ★대화형 웹사이트를 구축할 수 있다.

DOM을 업데이트하지만 HTML 소스코드 문서의 내용을 변경하진 않는다.
⇒ DOM에 접근하여 HTML element 의 속성을 변경하거나 기타 기능을 구현할 수 있음. (document 속성을 사용해서 DOM에 접근할 수 있다.)

cf. defer 속성
전체문서가 분석되기까지 스크립트 실행이 지연되어야 한다고 브라우저에게 알리는 역할이다.

<script src="demo.js" defer></script>

DOM 트리

브라우저가 HTML 문서를 로드한 후 파싱하여 생성하는 모델을 의미한다.
=> 각 객체(요소, 어트리뷰트, 텍스트)들이 Tree형태로 구조화 되어있어 DOM Tree라 칭한다.

4종류의 노드로 구성된다.

  1. 문서 노드 (엔트리 포인트)
  2. 요소 노드
  3. 어트리뷰트 노드
  4. 텍스트 노드 (최종점)

DOM element에 접근하기 (DOM Query)

  1. 요소를 파헤치는 방법 (drill)
  2. e.g. document.body.children[0].firstChild ⇒ 대신 정확한 구조를 파악해야함.
  3. 유틸리티 함수로 특정요소를 쿼리
  4. (1) document.getElementById()
    id에 일치하는 요소노드 중 첫번째 요소를 반환.
    (2) document.querySelector();
    => CSS selector 사용하여 해당 엘리먼트 노드 중 첫번째 요소를 반환
    (3) document.querySelecorAll()
    => 마찬가지로 셀렉터 사용하여 해당 요소 노드를 '모두' 선택한다.

HTML 콘텐츠 조작하기

  1. textContent
    => 요소의 텍스트 콘텐츠를 취득, 변경이 가능하다.
const ul = document.querySelector('ul');
console.log(ul.textContent);
  1. innerText
    => 비표준이고, CSS에 순종적이라한다.(visibility: hidden; 지정되어있으면 텍스트가 반환X), 그리고 CSS 고려해야해서 textContent보다 느리다.
  2. innerHTML
    => 모든 콘텐츠를 하나의 문자열(마크업 포함)로 취득할 수 있고, 새로운 요소를 DOM에 삽입할 수도 있다.

DOM 조작 - 추가

  1. createElement()
    태그이름을 인자로 전달하여 element를 생성
  2. const myLi = document.createElement(li);
  3. createTextNode()
    텍스트를 전달하여 텍스트 노드를 생성
  4. const newText = document.createTextNode('bae');
  5. appendChild()
    인자로 전달한 노드를 마지막 자식요소로 DOM 트리에 추가
  6. myLi.appendChild(newText);

cf. insertAdjacentHTML()
인자로 전달한 텍스트를 HTML로 파싱하고 생성된 노드를 DOM 트리의 지정된 위치에 삽입

  • beforebegin
  • afterbegin
  • beforeend
  • afterend

insertAdjacentHTML이나 innerHTML은 크로스 스크립팅 공격에 취약하다고 한다.

=> 따라서 텍스트를 추가하거나 변경할때는 textContent()를 사용하고,
새로운 element를 추가하거나 삭제할때는 DOM 조작 방식을 사용하도록 하자.

 

 

 

참고: https://poiemaweb.com/js-dom

문제링크

https://school.programmers.co.kr/learn/courses/30/lessons/42587?language=python

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

문제설명

 

문제 설명
운영체제의 역할 중 하나는 컴퓨터 시스템의 자원을 효율적으로 관리하는 것입니다. 이 문제에서는 운영체제가 다음 규칙에 따라 프로세스를 관리할 경우 특정 프로세스가 몇 번째로 실행되는지 알아내면 됩니다.

1. 실행 대기 큐(Queue)에서 대기중인 프로세스 하나를 꺼냅니다.
2. 큐에 대기중인 프로세스 중 우선순위가 더 높은 프로세스가 있다면 방금 꺼낸 프로세스를 다시 큐에 넣습니다.
3. 만약 그런 프로세스가 없다면 방금 꺼낸 프로세스를 실행합니다.
  3.1 한 번 실행한 프로세스는 다시 큐에 넣지 않고 그대로 종료됩니다.
예를 들어 프로세스 4개 [A, B, C, D]가 순서대로 실행 대기 큐에 들어있고, 우선순위가 [2, 1, 3, 2]라면 [C, D, A, B] 순으로 실행하게 됩니다.

현재 실행 대기 큐(Queue)에 있는 프로세스의 중요도가 순서대로 담긴 배열 priorities와, 몇 번째로 실행되는지 알고싶은 프로세스의 위치를 알려주는 location이 매개변수로 주어질 때, 해당 프로세스가 몇 번째로 실행되는지 return 하도록 solution 함수를 작성해주세요.

제한사항
priorities의 길이는 1 이상 100 이하입니다.
priorities의 원소는 1 이상 9 이하의 정수입니다.
priorities의 원소는 우선순위를 나타내며 숫자가 클 수록 우선순위가 높습니다.
location은 0 이상 (대기 큐에 있는 프로세스 수 - 1) 이하의 값을 가집니다.
priorities의 가장 앞에 있으면 0, 두 번째에 있으면 1 … 과 같이 표현합니다.

 

문제풀이

    
우리는 location에 해당하는 프로세스가 언제 실행되는지 알고싶은거임.

 

# priorities에 있는 숫자들은 말그래도 각 프로세스의 우선순위를 의미.

# [1, 1, 9, 1, 1, 1]
# => [C, D, E, F, A, B]
# 프로세스 번호는 priorities의 인덱스 번호라고 하자.
# 그럼 큐에 저장을 할때 (key, value) 형태로 저장하면 좋겠지?
# => key = 인덱스번호, value = 우선순위값

코드
from collections import deque

def solution(priorities, location):
    answer = 0
    queue = deque([(priority, key) for (key, priority) in enumerate(priorities)])   # 우선순위값과 프로세스번호(인덱스)를 튜플로 묶어 큐에 삽입.
 

    # 큐가 남아있을 동안 pop은 계속됨.
    while queue:
        curPriority, curKey = queue.popleft()   # (우선순위, 프로세스번호)를 pop함.
        
        # cur와 배열안의 나머지숫자들과 비교.
        if all(curPriority >= item for (item, key) in queue):
            answer += 1
            # 알고싶은 위치의 프로세스 넘버라면 return.
            if curKey == location:
                return answer
        else:
            queue.append((curPriority, curKey))

 

 

자바스크립트로도 풀었다.

function solution(priorities, location) {
    let queue = priorities.map((priority, index) => ({ priority, index}));
    let answer = 0;
    
    while (queue.length) {
        let cur = queue.shift();
        
        // 현재 프로세스의 우선순위가 더 작은게 있다면 현재프로세스는 다시 큐에 삽입
        if (queue.some(item => item.priority > cur.priority)) {
            queue.push(cur);
        } else {
            answer += 1
            if (cur.index === location) {
                return answer;
            }
        }
    }
    
}
문제링크

https://school.programmers.co.kr/learn/courses/30/lessons/42747?language=python3

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

문제설명

 

문제 설명

H-Index는 과학자의 생산성과 영향력을 나타내는 지표입니다. 어느 과학자의 H-Index를 나타내는 값인 h를 구하려고 합니다. 위키백과1에 따르면, H-Index는 다음과 같이 구합니다.

어떤 과학자가 발표한 논문 n편 중, h번 이상 인용된 논문이 h편 이상이고 나머지 논문이 h번 이하 인용되었다면 h의 최댓값이 이 과학자의 H-Index입니다.

어떤 과학자가 발표한 논문의 인용 횟수를 담은 배열 citations가 매개변수로 주어질 때, 이 과학자의 H-Index를 return 하도록 solution 함수를 작성해주세요.

제한사항
과학자가 발표한 논문의 수는 1편 이상 1,000편 이하입니다.
논문별 인용 횟수는 0회 이상 10,000회 이하입니다.

문제풀이

 

H-Index 란, h번 이상 인용된 논문이 h편이상, 나머지가 h번 이하 인용됐을때

그때의 h중의 최댓값이 H-index라고 한다.
    
citations  - 발표한 논문의 인용횟수 들이 담긴 배열
len(citations)  - 발표 논문 수

 

테스트케이스 입력값을 예로 들면 citations = [3, 0, 6, 1, 5]

i 0 1 2 3 4
citations[i] 6  5  1 0

 

1. 일단 내림차순 정렬을 한다

왜? => h번이상 인용된 논문수가 인용횟수보다 커야하므로, 그리고 그중에서 최댓값을 찾아야하므로

 

 

citations 값이 i보다 크면, 계속 개수를 세어준다.

작거나 같아지는 지점( if citations[i] <= i: )에 도달하면 i값을 return한다. 

=> 더이상 i번 이상 인용된 논문이 없다는 뜻이므로.

 

 

코드
def solution(citations):
    answer = 0
    n = len(citations)
    
    citations.sort(reverse=True);
    
    for i in range(n):
        if i >= citations[i]:
            return i
    return n

 

자바스크립트로도 풀었다.

function solution(citations) {
    let answer = 0;
    let n = citations.length;
    
    citations.sort((a, b) => b - a);    //내림차순 정렬
  
    // i    0 1 2 3 4
    // c[i] 6 5 3 1 0
    
    for (let i = 0; i < n; i++) {
        if (i >= citations[i]) {
            answer = i
            return answer
        }
    }
    return n
}
문제링크

https://school.programmers.co.kr/learn/courses/30/lessons/42746?language=python3

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

문제설명

 

문제 설명
0 또는 양의 정수가 주어졌을 때, 정수를 이어 붙여 만들 수 있는 가장 큰 수를 알아내 주세요.

예를 들어, 주어진 정수가 [6, 10, 2]라면 [6102, 6210, 1062, 1026, 2610, 2106]를 만들 수 있고, 이중 가장 큰 수는 6210입니다.

0 또는 양의 정수가 담긴 배열 numbers가 매개변수로 주어질 때, 순서를 재배치하여 만들 수 있는 가장 큰 수를 문자열로 바꾸어 return 하도록 solution 함수를 작성해주세요.

제한 사항
numbers의 길이는 1 이상 100,000 이하입니다.
numbers의 원소는 0 이상 1,000 이하입니다.
정답이 너무 클 수 있으니 문자열로 바꾸어 return 합니다.

 

문제풀이

 

처음에는 다음과 같은 생각을 하였다.

순서 재배치하여 만들 수 있는 가장 큰수 구하기 문제.

 

정렬을 하자
    # => 여러자리수라면 가장 앞자리를 보면 될듯?, 그다음 다음자리수 이렇게

    # 요구사항
    # 1. 숫자가 큰 아이템부터 배치.
    # 2. 숫자가 두자리 수 이상이라면 맨 앞자리부터 비교하여 큰 숫자 부터 배치
    # 3. 한자리수와 두자리수이상의 숫자를 비교할때 같은 방식으로 비교하되,
    #    한자리수가 두자리수이상숫자의 각자릿수 숫자들 보다 한개라도 더 큰게 있다면  (예를 들어 3 vs 30)
    #    한자리수를 먼저 배치.

 

파이썬에서 문자열 대소비교

문자열은 사전순서대로 비교된다.

 

3 vs 30 을 비교한다고 하면

(1) 첫번째 3이 같으므로 다음자릿수로 넘어간다.

(2) 3은 두번째 문자가 없지만, 30은 0 이라는 문자가 있어 30이 더 큰것으로 처리된다.

 

그러나 33과 3030을 비교한다고 하면,

(1) 3이 같으므로 다음자릿수로 넘어감

(2) 3 vs 0 인데 3이 더 크므로 33이 더 큰 문자열인 것으로 처리된다. 

 

핵심

1. 각 배열의 숫자를 문자열로 변환
2. 정렬함수 활용해 내림차순 정렬
3. 이때 각 문자열에 *3을 해주어 길이를 늘린후 정렬.
=> 테스트케이스로 나올 수 있는 원소범위가 1000이하이기 때문에
하지만 1000은 4자리수 아닌가 싶었지만,
하지만 1000은 1이랑 비교해도 3배로 늘린다면
100010001000 vs 111 
=> 111이 더 큰것으로 처리되므로 문제 X

마지막에

int() 변환후 다시 str() 변환해야 테스트케이스 통과됨.

코드
def solution(numbers):
    answer = ''
    
    for i in range(len(numbers)):
        numbers[i] = str(numbers[i])

    numbers.sort(key=lambda x: x*3, reverse=True)
    
    for item in numbers:
        answer += item
   
    return str(int(answer))

 

 

자바스크립트로 풀면

function solution(numbers) {
    var answer = '';
    
    stringArr = numbers.map(item => String(item));
    answer = stringArr.sort((a, b) => (b + a) - (a + b)).join('');
    
    return answer[0] === "0" ? "0" : answer;
}

 

벌써 2주차가 끝났다..

이제 사람들과도 어느정도 말도 많이 하고 적응이 된 것 같다. 

오프라인이라는 특성 덕분에 vod 강의를 수강하더라도 동기들과 함께 집중해서 들을 수 있어서 그것이 내가 생각하기에 가장 큰 장점인 것 같다.

또 팀스터디 시간에 진행할 내용을 각자 구글링을 통해 학습하며 추가적으로 보완하고 싶은 부분은 보완하고, 함께 공부하며 성장하는 느낌을 받아 좋은 시간이었다.

 

가장 인상 깊은 점은 유데미 강의의 HTML 강의는 퀄리티가 꽤 높은 것 같다.

예를 들어 HTML 폼을 구현하는 실습을 할 때도,

시멘틱 태그를 최대한 활용하고, 단순히 UI 구현이 목적이 아닌 유지보수나 가독성을 높이기 위해 코드 퀄리티면에서 신경을 쓰는 부분에서 느낄 수 있었다.

다음 주차는 자바스크립트를 학습한다고 한다.

프론트엔드 개발의 가장 기초이자 중요한 부분이니 이번 기회에 부족한 부분을 더 채우며 성장할 수 있도록 많은 노력을 더 기울여야 겠다.

 

2주동안 배우고 또 개인적으로 학습한 내용은 아래 학습내용에 정리를 했다.

 

git 명령어

Merge conflict

서로다른 브랜치 혹은 서로 다른 사용자가,
같은 파일의 같은 코드부분을 수정하고 병합하려고 할때 발생한다.

해결방법은 충돌이 발생한 파일을 열고, git이 표시한 충돌 부분에서 어느 코드를 유지할지 결정하고 변경하면 된다.
=> 충돌난 부분을 작성한 팀원과 꼭 상의가 필요할 것 같다.

fork, clone

둘다 레포지토리 전체내용을 나의 독립적인 저장소로 가져오는 명령어이다.
차이점은,
fork는 원격에서 원격으로
clone은 원격에서 로컬로 받아온다.

fetch vs pull

git fetch 명령어는 원격저장소에 변경사항이 있는지 "확인"만 한다.
git pull은 원격저장소의 변경사항을 로컬로 받아와 merge까지 수행한다.

 

CSS 포지셔닝

Flex box의 장점

  1. 플렉스 박스에 속한 엘리먼트들의 정렬, 순서변경에 용이하다.
  2. 유연한 특성이 있어, flex-grow, flex-shrink, flex-basis 등의 속성을 통해 각 아이템이 차지하는 유연하게 조절할 수 있다.
    => 다양한 화면 크기(높이, 너비)에 맞게 아이템들이 조정되어 반응형 레이아웃 구현에 효과적이다!
    1. 무엇보다 코드가 간소화된다. => 가독성 유지보수성 증대
    cf. display 속성에는 무엇이 있나요??

 

cf. 높이를 고정값으로 설정하는게 좋지 않은 이유는?
고정된 높이보다 콘텐츠 양이 더 많을때 잘릴 수 있고, 사용자의 해상도 차이가 있을경우 적절한 UX를 제공하기가 어려움.
따라서 고정값이 아닌 min-height를 이용하여 다양한 장치에서의 화면크기에 유연하게 조절가능하도록 한다.

 

Form 엘리먼트

input : type 속성값으로 email, date, password, checkbox, radio 등이 있다.
textarea : input 요소에 반해 댓글이나, 사용자 피드백 등 긴 텍스트를 받기 위해 사용하는 태그.
select : 드랍다운을 만들어서 사용자가 하나를 선택하게 하는 태그
button : 버튼 태그

 

cf. hr태그를 사용하면 수평 가로선이 생긴다. 주제가 바뀌거나 할 때 용이할 듯 하다.

 

 

이번 2주차의 TIL 링크

https://baegopeun-sj.tistory.com/138

https://baegopeun-sj.tistory.com/142

https://baegopeun-sj.tistory.com/143

https://baegopeun-sj.tistory.com/144

https://baegopeun-sj.tistory.com/145

학습내용


원시타입 vs 객체

원시타입(★불변성, 데이터의 신뢰성 보장)

  • 메모리에 실제값 저장
  • 값에 의한 전달 (원시 값이 복사되어 전달)

객체(프로퍼티 접근을 위해 히든클래스 방식)

  • 메모리에 주소값 저장
  • 참조에 의한 전달 (원본의 주소값이 복사되어 전달된다.)
  • 두 개의 식별자가 하나의 객체 공유 가능.

함수와 메서드

함수
사용이유 - 코드의 재사용성, 유지보수성, 가독성
JS에서 함수는 일급 객체다

메서드: 프로퍼티 값이 함수인 경우를 메서드라고 함

함수선언문과 함수표현식

함수선언문
=> 함수 선언문의 경우 JS엔진이 생성된 함수를 호출하기 위해 함수 이름과 동일한 식별자를 암묵적으로 생성하여 함수객체에 접근하고 호출할 수 있음.
(JavaScript 엔진은 함수 선언문에서 함수 이름과 동일한 식별자를 전역 스코프에 추가적으로 만들어 함수 객체를 할당.)

함수표현식 (함수 리터럴)

  • 자바스크립트에서 함수는 일급객체라는 특성을 이용하여 함수 리터럴 방식으로 함수를 정의.

  • 변수에 할당 가능.

  • 기명보다는 익명함수 즉, 함수명을 생략하는게 일반적임.

cf. https://baegopeun-sj.tistory.com/53


null vs undefined

  • 무엇인가가 초기화되지 않음 => undefined
  • 무엇인가를 초기화한후 의도적으로 null값 할당. => null
    ※ null을 사용하지 않는 것이 바람직하다고 함.
    null대신 undefined 사용하자. -더글락스 크록포드-

localStorage

브라우저 환경에서만 동작한다. (Node.js환경에서 동작X)

  • 브라우저가 제공하는 기능이기 때문에. (클라이언트 측 데이터 저장과 관리를 위해)
  • 브라우저의 도메인과 연결되는데, 이는 다른 도메인에서 접근하지 못하도록 하는 그런 보안적인 문제때문에.

실행 컨텍스트

블로그 참고
https://baegopeun-sj.tistory.com/26

학습내용


  1. 웹사이트 구현시 step by step으로 하자 (큰 틀을 먼저 잡고, 부가적인 것을 채워나가는 방식)
  2. 페이지의 핵심정보를 생각해라 (요구사항 명확히하자)
  3. less is more (심플하고 단정하게만 하자)

cf. 항상 컨텐츠에는 필요한 것 보다 많은 공간을 부여하는게 좋다. (나중에 간격이나, 마진,패딩 줄일 일이 있을 수 있기 때문에)

transform

자연스러운 변화 구현이 가능

button {
    transition: background-color 0.5s ease-out;
}

button:hover {
    background-color: red;
}

SVG

브라우저가 렌더링 할 수 있는 확장형 이미지의 텍스트 기반 묘사이다.

복잡한 이미지에는 적용되지 않음.
아이콘이나 쉬운 이미지는 가능!

Form 엘리먼트

input : type 속성값으로 email, date, password, checkbox, radio 등이 있다.
textarea : input 요소에 반해 댓글이나, 사용자 피드백 등 긴 텍스트를 받기 위해 사용하는 태그.
select : 드랍다운을 만들어서 사용자가 하나를 선택하게 하는 태그
button : 버튼 태그

radio, checkbox의 차이

checkbox는 값을 여러개 받을 수 있다. radio는 값을 한개만 받을 수 있다.
checkbox를 여러개 만든다면 서버가 추출할 수 있도록 식별자를 value속성을 통해 부여하자!

cf. 회원가입 같은 폼을 만들때 여백이나 너비등을 맞추기 위해 input, textarea, select 등을 함께 선택해서 css 스타일을 적용하는 것 같다.

cf. hr태그를 사용하면 수평 가로선이 생긴다. 주제가 바뀌거나 할 때 용이할 듯 하다.

required, aria-required 속성

required 속성은 브라우저의 기본 유효성 검사 기능에 해당한다.
(기본 유효성 검사기능 속성으로 required, minlength, min, max 등 속성 사용이 가능하다.)

aria-required 속성은 "스크린 리더 사용자"들에게 해당 필드가 필수임을 알려주는 역할이다.

HTTP

개발자 도구 네트워크 탭을 보다가 keep-alive 옵션을 보고 CS스터디 때 공부했던 내용이 생각났다.

HTTP/1.0 때는 한번의 연결당 하나의 요청만을 처리하도록 설계되어서 RTT가 증가했다!(계속 TCP 3-way handshake 연결 해야하니까)
RTT를 줄이기 위해 HTTP/1.1 부터는 keep-alive 옵션이 생겼다.
해당 기능을 통해 한번의 HTTP요청/응답 후에도 연결을 바로 종료하지 않고 일정시간동안 열어놓아, 리소스 오버헤드를 줄일 수 있다!.

하지만 이런 HTTP/1.1 에도 여러가지 문제점들이 있었다
cf. HTTP

+ Recent posts