가장 큰 수 찾기
str은 무작위 숫자인 문자열입니다. 해당 문자열에서 가장 큰 수를 구하는 함수를 만들어야 합니다.
주의 사항
- str에서 각각의 문자를 숫자로 바꿔서 계산해야 합니다.
- 비교할 수 있는 기준값이 있어야 합니다.
- 최댓값을 저장할 수 있는 변수가 있어야 합니다.
// 내 코드
function bigNum(str) {
let num = Number(str) // 숫자로 먼저 변환을 해주면 나중에 index로 접근을 못함...
let biggest = 0;
//기준값을 뭘로 잡지?
for(i = 0; i < str.length; i++) {
if(num[i] > biggest){
biggest = num[i];
}
}
return biggest;
}
bigNum("12345") // 5
bigNum("87135") // 8
// reference code
function bigNum(str) {
let biggest = 0;
for(i = 0; i < str.length; i++) {
if(Number(str[i]) > biggest){ //biggest 가 0으로 선언되었기 때문
biggest = Number(str[i]);
}
}
return biggest;
}
bigNum("12345") // 5
bigNum("87135") // 8
조건문 실전 적용 - 점수에 따른 등급
100~90 → "A"
89~80 → "B"
79~70 → "C"
69~60 → "D"
59점 이하는 "F"
100점 초과나 0점 미만은 "잘못된 점수입니다"라는 문구를 띄워주세요.
function grade(score) {
if(score > 100 || score < 0){ //조건을 수정해 줄 때 가장 마지막 조건부터 소거법 형태로
return "잘못된 점수입니다"
}
else if(score <= 59){
return "F"
}
else if(score <= 69){
return "D"
}
else if(score <= 79){
return "C"
}
else if(score <= 89){
return "B"
}
else {
return "A"
}
}
grade(105) // "잘못된 점수입니다"
grade(-10) // "잘못된 점수입니다" => 해당 케이스때문에 오류
grade(97) // "A"
grade(86) // "B"
grade(75) // "C"
grade(66) // "D"
grade(52) // "F"
마이페이지
해당 목록에서 "의류"를 구매한 횟수와 총 금액을 나타내고,
"의류"를 구매한 횟수에 따라 등급을 나타내세요.
등급표
"0~2" ⇒ Bronze
"3~4" ⇒ Silver
5이상 ⇒ Gold
예상결과
의류를 구매한 횟수는 총 5회 금액은 57000원이며 등급은 Gold입니다.
const myShopping = [
{ category: "과일", price: 12000 },
{ category: "의류", price:10000 },
{ category: "의류", price: 20000 },
{ category: "장난감", price: 9000 },
{ category: "과일", price: 5000 },
{ category: "의류", price: 10000 },
{ category: "과일", price: 8000 },
{ category: "의류", price: 7000 },
{ category: "장난감", price: 5000 },
{ category: "의류", price: 10000 },
]
//횟수 변수 선언
let count = 0
// 금액 변수 선언
let amount = 0
// 등급 변수 선언
let grade = ''
for(i = 0; i < myShopping.length; i++){
if(myShopping[i].category === "의류"){ //배열안에 객체의 value 접근
count = count + 1;
amount = amount + myShopping[i].price;
}
}
if(count >= 5) {
grade = "Gold"
}
else if(count >= 3){
grade = "Silver"
}
else {
grade = "Bronze"
}
let credit =`의류를 구매한 횟수는 총 ${count}회 금액은 ${amount}원이며 등급은 ${grade}입니다.` // 템플릿 리터럴
console.log(credit)
Cross-Origin-Resource-Sharing
서로 다른 출처(origin)를 가진 주소로 요청이 들어왔을 때 발생할 수 있는 에러
i.e) url(http://localhost:3000/tokens/phone) => http://localhost:3000을 origin 이라 함
port번호가 다른 경우에도 CORS 에러는 발생하는데 이는 같은 localhost임에도 다른 출처로 인식되기 때문임
import cors from 'cors'; //import
...
const app = express();
app.use(express.json());
app.use(cors()); // 추가된 부분
...
app.use(cors({origin: }))
과 같이 작성하여 특정 origin만을 허용하도록 설정// const { ApolloServer, gql } = require('apollo-server');
import { ApolloServer, gql } from 'apollo-server'
// The GraphQL schema
const typeDefs = gql`
type Query {
"A simple type for getting started!"
hello: String
}
`;
// A map of functions which return data for the schema.
const resolvers = { //express 서버를 사용할 때 보았던 api와 같은 역할
Query: {
hello: () => 'world',
},
};
const server = new ApolloServer({
typeDefs,
resolvers,
}); //resolvers라는 객체 안에 있는 Query 객체에 작성해 놓은 hello 함수가 실행되면서
//typeDefs 객체 안에 있는 type Query 객체에 지정해 놓은 데이터의 형태로 반환
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
resolvers :express 서버를 사용할 때 보았던 api와 같은 역할
// express
app.get('/', function (req, res) {
res.send('Hello Wordld')
})
// apollo-server
const resolvers = {
Query: {
hello: () => 'Hello world',
},
};
typeDefs : express의 경우 swagger를 통해 api-docs를 직접 작성해주었는데 graphql의 경우 해당 부분을 typeDefs에서 swagger와 같이 api-docs를 자동으로 생성
const resolvers = {
Query: {
fetchBoards: () => {
// 1. 데이터를 조회하는 로직 => DB에 접속해서 데이터 꺼내오기
const result = [
{
number: 1,
writer: '철수',
title: '제목입니다~~',
contents: '내용이에요@@@',
},
{
number: 2,
writer: '영희',
title: '영희 제목입니다~~',
contents: '영희 내용이에요@@@',
},
{
number: 3,
writer: '훈이',
title: '훈이 제목입니다~~',
contents: '훈이 내용이에요@@@',
},
];
// 2. 꺼내온 결과 응답 주기
return result;
},
},
}
// 기본 세팅
const resolvers = {
Mutation: {
createBoard: (parent, args, context, info) => {
},
},
};
parent
: 부모 타입 resolver에서 반환된 결과를 가진 객체args
: 쿼리 요청 시 전달된 parameter를 가진 객체context
: GraphQL의 모든 resolver가 공유하는 객체로서 로그인 인증, 데이터베이스 접근 권한 등에 사용info
: 명령 실행 상태 정보를 가진 객체const resolvers = {
Query: {
fetchBoards: () => {
// ...
},
},
Mutation: {
createBoard: (_, args) => {
// 1. 데이터를 등록하는 로직 => DB에 접속해서 데이터 저장하기
console.log(args);
// 2. 저장 결과 응답 주기
return '게시물 등록에 성공하였습니다!!';
},
},
};
// Rest-API에서는 요청 데이터를 확인하기 위해 매개변수로 **req**를 사용
//GraphQL-AP에서는 4개의 매개변수 중 요청 데이터를 확인 가능한 **args**를 사용하여
// 입력값을 가져옴
// 사용하지 않는 매개변수는 _(언더바)로 선언
const typeDefs = gql`
input CreateBoardInput { //input을 사용해 데이터의 타입을 지정
writer: String
title: String
contents: String
}
type Mutation {
# createBoard(writer: String, title: String, contents: String):
# String => 입력값을 낱개로 받아오는 것을 의미
createBoard(createBoardInput: CreateBoardInput!): String
# => 입력값을 객체로 받아오는 것을 의미
}
`;
// Rest-api
import express from 'express'
import { checkValidationPhone, getToken, sendTokenToSMS } from './phone.js'
import swaggerUi from 'swagger-ui-express'
import swaggerJsdoc from 'swagger-jsdoc'
import { options } from './swagger/config.js'
const app = express()
app.use(express.json())
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerJsdoc(options)));
app.get('/boards', (req, res) => {
const result = [
{ number: 1, writer: "철수", title: "제목입니다", contents: "내용입니다" },
{ number: 2, writer: "영희", title: "좋은 날씨입니다", contents: "내용입니다" },
]
res.send(result)
})
app.post('/tokens/phone', (req, res) => {
const myphone = req.body.myphone
// 1. 휴대폰번호 자릿수 맞는지 확인하기
const isValid = checkValidationPhone(myphone)
if(isValid){
// 2. 휴대폰 번호 자릿수가 맞다면 핸드폰 토큰 4자리 만들기
const mytoken = getToken()
// 3. 만든 토큰을 핸드폰번호에 토큰 전송하기
sendTokenToSMS(myphone, mytoken)
res.send("인증완료!!!")
}
})
app.listen(3000, () => {
console.log(`Example app listening on port ${3000}`)
})
///Graphql-api
number: 1,
writer: "철수",
title: "제목입니다",
contents: "내용입니다",
},
{
number: 2,
writer: "영희",
title: "좋은 날씨입니다",
contents: "내용입니다",
}
];
},
},
Mutation: {
createTokenOfPhone: (_, args) => {
// 2. 아래 로직을 만들어 주세요.
// (힌트: phone.js 내에 존재하는 함수들을 사용해서 로직을 완성해 주시면 됩니다.
// 로직 구성이 어려우신 분들은 rest_api 폴더 내에 존재하는 index.js 파일을 참고해 주세요.)
const myphone = args.phone;
// 2-1. 휴대폰번호 자릿수 맞는지 확인하기
const isValid = checkValidationPhone(myphone)
if(isValid === false){
return
}
// 2-2. 휴대폰 번호 자릿수가 맞다면 핸드폰 토큰 4자리 만들기
const myToken = getToken()
// 2-3. 만든 토큰을 핸드폰번호에 토큰 전송하기
sendTokenToSMS(myphone,myToken)
return "인증완료"
},
},
};
const server = new ApolloServer({
typeDefs,
resolvers,
});
server.listen(3000).then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
import express from 'express'
import swaggerUi from 'swagger-ui-express'
import swaggerJsdoc from 'swagger-jsdoc'
import {options} from './swagger/config.js'
import cors from 'cors'
const app = express()
app.use(express.json())
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerJsdoc(options)));
app.use(cors())
app.get('/users',(req,res)=>{
const result = [
{
email : "aaa@gmail.com",
name : "철수",
phone : "010-1234-5678",
personal : "220110-1******",
prefer : "https://naver.com"
},
{
email : "hoon2@gmail.com",
name : "훈이",
phone : "010-7272-2727",
personal : "221012-1******",
prefer : "https://google.com"
},
{
email : "glass@gmail.com",
name : "유리",
phone : "010-6262-2626",
personal : "220509-2222222",
prefer : "https://daum.com"
},
{
email : "mangGu@gmail.com",
name : "맹구",
phone : "010-0909-9090",
personal : "221227-1******",
prefer : "https://yahoo.com"
},
{
email : "GGang@gmail.com",
name : "짱구",
phone : "010-9090-0909",
personal : "220505-1******",
prefer : "https://youtube.com"
}
]
res.send(result)
})
app.get('/starbucks',(req,res)=>{
const coffee = [
{ name: '아메리카노', kcal: 5 },
{ name: '카라멜 마키야또', kcal: 400 },
{ name: '바닐라 라떼', kcal: 450 },
{ name: '초코 라떼', kcal: 480 },
{ name: '그린티 라떼', kcal: 350 },
{ name: '고구마 라떼', kcal: 380 },
{ name: '콜드브루', kcal: 5 },
{ name: '에스프레소', kcal: 3 },
{ name: '초코 바나나스무디', kcal: 600 },
{ name: '바나나 딸기스무디', kcal: 550 }
]
res.send(coffee)
})
app.listen(3000, () => {
console.log(`백엔드 api 서버가 켜졌어요`)
})