코트카타
11) 홀수와 짝수
class Solution {
public String solution(int num) {
String answer = "";
if(num%2==0){
answer="Even";
} else {
answer="Odd";
}
return answer;
}
}
삼항연산자로도 문제를 풀 수 있다.
괄호 안의 조건이 참이면 Even, 거짓이면 Odd를 반환하는 것이다.
(num % 2 == 0) ? "Even" : "Odd";
출처 : https://school.programmers.co.kr/learn/courses/30/lessons/12937/solution_groups?language=java
나는 코트 카타를 할 때, 해당 문제를 풀기에만 급급한데,
다른 분들의 풀이를 보면 보다 간결한 코드에 대해 고민하시는 것 같다.
내가 삼아야 할 지향점이라고 생각한다.
12) 평균 구하기
class Solution {
public double solution(int[] arr) {
double answer = 0;
double sum = 0;
if(arr.length>=1 && arr.length<=100){
for(int i : arr){
if(i>=-10000 && i<=10000){
sum += i;
}
}
answer = sum / arr.length;
}
return answer;
}
}
내 현재 실력에서 배열에는 확장된 for문을 쓰기로 마음 먹었다.
아래는 stream 이용한 다른 분의 풀이이다.
return Arrays.stream(arr).average().getAsDouble();
출처:https://school.programmers.co.kr/learn/courses/30/lessons/12944/solution_groups?language=java
그런데 댓글을 보니 실행하면 엄청 느리다는 반응도 있다.
코드의 간결성도 중요하지만, 실행했을 때의 속도도 같이 고려해야 되겠다.
GIT 기초 특강 복습
3. Git 필수 명령어
저장 여부 확인하는 명령어 git status
코드의 변경은 있지만 저장을 하지 않은 파일 (붉은색으로 표시)
어제의 git 충돌 문제로 인해...
나는 pull를 하고 나서 바로 push 하지 않고
오류가 발생하지는 않았는지
git status와 git log를 꼭 확인하고 나서 push 하기로 했다.
그럼에도 충돌이 발생했다면 팀원들에게 상황 공유하며 해결하기로 했다.
내 프로젝트의 변경사항을 한 번에 지정하는 법
1. git add.
2. git commit -m "메세지 작성"
저장 내역을 확인하는 명령어 git log
커밋 메시지로 코드 변경점 추측 가능
git diff : 코드 변경 확인
git reset : 과거로 돌아가기 가능
4. Github 으로 코드 백업하기
1. 온라인 저장소 (github repository)를 만들기
1) Github 회원가입 및 로그인 진행
2) New 버튼 클릭
3) 레포지토리 이름을 입력하고,create을 클릭
2. 내 코드를 Github repository)로 업로드하기
1) 업로드할 프로젝트 폴더를 vsc로 열기
2) 붉은 박스의 명령어들을 복사
3) VSC의 터미널에 붙여넣기
4) Github 레포지토리로 코드가 잘 올라갔는지 확인
3.추가로 수정된 코드 github에 반영하기- git push
1) 코드 수정
2) 코드 저장 명령어 실행
ㄴ git add . & git commit -m "메시지"
3) git push origin 브랜치명
4. Github 협업하기+충돌 해결하기
1. 협력자(collaborator) 등록하기
1) Github 레포지토리 -> Settings -> Collaborators -> Add people 클릭
2) 팀원들의 username 혹은 email로 추가 => 초대 수락해야 합니다.
2. 코드 복사해오기 git clone
1) Github 레포지토리에서 github 주소를 복사합니다.
2) 코드를 작성할 폴더를 만들어 줍니다.
3) vsc에서 해당 폴더를 열어줍니다.
4) git clone <github 주소> . 명령어를 입력해줍니다.
3. 다른 사람이 변경한 코드 내 코드에도 가져오기 git pull
4. 충돌(Conflict) 해결하기
1) <<<<<<<<HEAD 삭제
2) ======== 삭제
3) >>>>>>> 4182 삭제
4) 원하는 코드로 수정
5) git add &git commit & git push
방명록 삭제 기능, 수정 기능 구현
css
/* 기본적으로 모달창 숨기기 */
.modal {
display: none; /* 기본적으로 숨겨져 있음 */
position: fixed; /* 전체 화면을 덮음 */
z-index: 1000; /* 최상위 레이어에 위치*/
left: 0;
top: 0;
width: 100%; /* 전체 화면을 덮음 */
height: 100%; /* 전체 화면을 덮음 */
overflow: auto;
background-color: rgba(0, 0, 0, 0.5); /* 반투명 검은 배경 */
}
/* 모달창 콘텐츠 */
.modal-content {
background-color: #fff; /*흰색 배경 */
margin: 15% auto; /*화면 중앙에 위치 */
padding: 20px;
border: 1px solid #888;
width: 80%; /*기본 너비 80%*/
max-width: 500px; /*최대 너비 500px,*/
text-align: center;
}
/* 닫기 버튼 */
.close {
color: #aaa;
float: right; /*우측 상단에 위치*/
font-size: 28px;
font-weight: bold;
cursor: pointer;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
JavaScript
//문서가 준비되면 매개변수로 넣은 콜백 함수를 실행하라
$(document).ready(function () {
eventListener();
getAllGstBook();
});
//이벤트 등록
const eventListener = () => {
//등록 버튼이벤트
$("#addGstBookBtn").on("click", () => {
let text = $("#gstbook_text").val();
let username = $("#gstbook_username").val();
let password = $("#gstbook_pw").val();
addGstBook({ text, username, password });
});
//방명록 삭제 이벤트 등록
$(".gstbook_list").on("click", ".deleteBtn", async function () {
const guestId = $(this).data("id"); // 버튼 ID에서 guestId 추출
const pass = $(this).data("password");
deleteGstBook(guestId, pass);
});
//방명록 수정 이벤트 등록
$(".gstbook_list").on("click", ".updateBtn", async function () {
const guestId = $(this).data("id"); // 버튼 ID에서 guestId 추출
const pass = $(this).data("password");
//해당 문서id의 데이터 중 key가 text인 value를 변수로 저장한다.
let docs = await getDoc(doc(db, "gst_book", guestId));
let row = docs.data();
const text = row["text"];
console.log("guestId", guestId, "수정");
updateGstBook(guestId, pass, text);
});
//입력시 알림메시지 사라지게
$("#gstbook_text").on("input", function () {
if ($(this).hasClass("is-invalid")) {
$("#gstbook_text").removeClass("is-invalid");
$("#gstbook_text").next(".invalid-feedback").remove();
}
});
$("#gstbook_username").on("input", function () {
if ($(this).hasClass("is-invalid")) {
$("#gstbook_username").removeClass("is-invalid");
$("#gstbook_username").next(".invalid-feedback").remove();
}
});
$("#gstbook_pw").on("input", function () {
if ($(this).hasClass("is-invalid")) {
$("#gstbook_pw").removeClass("is-invalid");
$("#gstbook_pw").next(".invalid-feedback").remove();
}
});
};
//필수값 안내 메시지
const showWarning = (message, id) => {
$(".invalid-feedback").remove();
//부트스트랩 유효성검사 사용
$(`#${id}`).addClass("is-invalid");
$(`#${id}`).after(`<span class="invalid-feedback">${message}</span>`);
$(`#${id}`).focus();
};
//유효성(필수값) 체크
const isValid = () => {
const text = $("#gstbook_text").val().trim();
const username = $("#gstbook_username").val().trim();
const password = $("#gstbook_pw").val().trim();
if (username === "") {
showWarning("작성자를 입력해주세요", "gstbook_username");
return false;
} else if (password === "") {
showWarning("비밀번호를 입력해주세요", "gstbook_pw");
return false;
} else if (text === "") {
showWarning("내용을 입력해주세요", "gstbook_text");
return false;
}
return true;
};
//방명록 추가
const addGstBook = async (data) => {
//유효하지않으면 종료
if (!isValid()) return;
let gstBookDoc = await addDoc(collection(db, "gst_book"), {
text: data.text,
username: data.username,
password: data.password,
create_dt: Date.now(),
});
getAllGstBook();
};
//방명록 삭제
const deleteGstBook = async (docId, pwd) => {
if (!docId) {
alert("삭제할 문서를 찾을 수 없습니다.");
return;
}
try {
// Firestore에서 문서 참조 생성 및 삭제
let gstBookDocId = doc(db, "gst_book", docId);
//console.log("삭제할 문서 ID:", gstBookDocId);
let getpass = prompt("비밀번호를 입력하세요.");
if (pwd == getpass) {
await deleteDoc(gstBookDocId);
alert("방명록이 성공적으로 삭제되었습니다.");
window.location.reload();
} else {
alert("비밀번호가 다릅니다.");
}
} catch (error) {
console.error("방명록 삭제 중 오류 발생:", error);
alert("방명록 삭제에 실패했습니다.");
}
};
//방명록 수정
const updateGstBook = async (guestId, pass, text) => {
if (!guestId) {
alert("수정할 문서를 찾을 수 없습니다.");
return;
}
let getpass = prompt("비밀번호를 입력하세요.");
if (pass == getpass) {
// 수정 버튼 클릭 시 모달창 표시
$("#modal").fadeIn(); // 부드럽게 표시
//해당 input의 value에 firebase에서 받아온 text 값을 넣기
$("#modal-content").val(text);
// 닫기 버튼 클릭 시 모달창 숨기기
$(".close").on("click", function () {
$("#modal").fadeOut(); // 부드럽게 숨김
});
// 모달창 외부 클릭 시 모달창 숨기기
// 전체 창(window)에 클릭 이벤트 리스너를 추가하기
$(window).on("click", function (event) {
// 클릭된 요소가 "#modal" ID를 가진 요소인지 확인
// 이는 모달의 배경(오버레이)을 클릭했는지 확인하는 것
// 헷갈릴 경우, 크롬 검사하기로 각 구간 확인하기
if ($(event.target).is("#modal")) {
// 조건이 참일 경우, "#modal" 요소에 jQuery의 fadeOut() 메서드를 적용합니다.
// fadeOut()은 요소를 서서히 사라지게 하는 내장 애니메이션 효과입니다.
$("#modal").fadeOut(); // 부드럽게 숨김
}
});
//방명록 수정 후 저장 이벤트 등록
$(".gstbook_list").on("click", ".saveBtn", async function () {
console.log("guestId", guestId, "저장");
saveGstBook(guestId, pass);
});
}
};
//방명록 수정 후 저장
const saveGstBook = async (guestId, pass) => {
// 컬렉션과 문서 ID 지정
const collectionName = "gst_book";
const documentId = guestId;
// 수정할 필드와 새 값 지정
const fieldToUpdate = "text";
// modal-content가 id인 input창의 value를 변수에 저장하기
const newValue = $("#modal-content").val();
// 문서 참조 생성
let docs = await getDoc(doc(db, "gst_book", guestId));
const ref = doc(db, collectionName, documentId);
console.log(ref);
// 필드 업데이트
await updateDoc(ref, { text: newValue });
window.location.reload();
};
//방명록 목록 가져오기
const getAllGstBook = async () => {
let allDocs = await getDocs(collection(db, "gst_book"));
let res = [];
let html = "";
//allDocs.docs 배열의 각 요소(doc)에 대해 반복 작업을 수행
allDocs.docs.map((doc) => {
//기존 res 배열의 모든 요소를 새 배열에 펼치고(...res), 새로운 객체를 추가
res = [
...res,
//새 객체를 생성. 이 객체는 doc.id를 id 속성으로 가지며,
//doc.data()의 모든 속성을 펼쳐서(...) 포함함
{
id: doc.id,
...doc.data(),
},
];
});
//생성일 기준 내림차순순
res.sort((a, b) => b.create_dt - a.create_dt);
//방명록 리스트 추가
res.forEach((data) => {
html =
html +
`<div id="${
data.id
}" class='pd-3' style='margin-bottom: 15px; border-bottom: 1px solid #ddd; padding-bottom: 10px;'>
<div style='font-weight: bold; color: #333; margin-bottom: 5px;'>${
data.username || "익명"
}</div>
<div style='color: #555; font-size: 14px; line-height: 1.5;'>${
data.text
}</div>
<div style='font-size: 12px; color: #999; margin-top: 5px;'>${new Date(
data.create_dt
).toLocaleString()}</div>
<button data-id=${data.id} data-password =${
data.password
} type="button" class="btn btn-outline-warning updateBtn">수정</button>
<button data-id=${data.id} data-password =${
data.password
} type="button" class="btn btn-outline-danger deleteBtn">삭제</button>
</div>
<div id="modal" class="modal">
<div class="modal-content">
<span class="close" id="closeButton">×</span>
<input id="modal-content" type="text" style='color: #555; font-size: 14px; line-height: 1.5;'></input>
<button data-id=${data.id} data-password =${
data.password
} type="button" class="btn btn-outline-success saveBtn">저장</button>
</div>
</div>
`;
});
$(".gstbook_list").empty();
$(".gstbook_list").append(html);
};
/* 방명록 로직 -끝 */
장점은 이전과 같이 hidden으로 태그를 숨여두고 데이터를 저장할 필요가 없다는 점
훨씬 HTMl 스크립트가 훨씬 간결해짐
또한 하나의 HTMl 요소에는 여러 데이터 속성을 동시에 사용가능
HTML
<!-- 방명록 시작-->
<div class="scroll_action_04 guestBook">
<div class="mt-2 p-5 bg-gray rounded">
<h2 class="fs-6">방명록 남기기</h2>
<div class="guestBook_input_top_wrapper">
<input
type="text"
class="form-control"
id="gstbook_username"
style="
margin-bottom: 7px;
border-radius: 4px;
border: 1px solid #ced4da;
width: 100px;
padding: 6px 12px 6px 12px;
"
placeholder="작성자"
/>
<input
type="password"
class="form-control"
id="gstbook_pw"
style="
margin-bottom: 7px;
border-radius: 4px;
border: 1px solid #ced4da;
width: 110px;
padding: 6px 12px 6px 12px;
"
placeholder="비밀번호"
/>
</div>
<input
class="form-control"
type="text"
style="height: 70px"
id="gstbook_text"
placeholder="내용"
/>
<div class="d-flex mt-2 justify-content-end">
<input
style="width: 100px"
type="submit"
class="btn btn-primary"
id="addGstBookBtn"
te
/>
</div>
<div class="gstbook_list"></div>
</div>
</div>
<!-- 방명록 끝-->
자바의 정석 - 객체지향
클래스 = 제품 설계도
객체 = 제품
클래스
- 객체를 정의해 놓은 것
- 객체를 생성하기 위해 필요함
객체
- 실제로 존재하는 것, 사물 또는 개념
- 객체 = 속성(변수) + 기능(메서드)
- 객체를 사용하기 위해서 필요함
- 객체를 사용한다는 것은 객체의 속성과 기능을 사용하는 것
1. 클래스 작성(설계도)
2. 변수 선언 (Tv t;)
3. 객체 생성 (t = new Tv();)
4. 변수를 사용해 객체 사용(변수, 메서드 호출)
-> Tv 객체가 만들어지면 t 변수에는 Tv 객체의 주소 값이 저장됨
두 사람이 한 사람 좋아하는 것은 가능
그러나 한 사람이 양다리는 불가능 ㅋㅋㅋ
클래스의 정의
-클래스
①설계도
②데이터+함수
③사용자 정의 타입 데이터+함수
-변수(하나의 데이터)→배열(같은종류만 저장)→구조체(서로 관련된 여러종류의 데이터)→클래스(구조체+함수)
사용자 정의 타입
-원하는 타입을 직접 만들 수 있음
-서로 관련된 데이터를 하나로 묶어서 객체지향적인 코드로 만들 수 있음
- 클래스 영역: 인스턴스 변수(iv), 클래스 변수(cv = static + iv)
- 메서드 영역: 지역변수(lv)
- 클래스 영역에는 선언문만 가능함
- 객체 = iv를 묶어놓은 것 (프로그래밍 관점)
- 인스턴스 변수는 객체가 생성될 때 만들어짐
- 클래스 변수는 클래스가 메모리에 올라갈 때 한 번만 만들어짐
- 지역변수는 변수가 선언되면 생성되서 메서드 종료 시 자동 제거
- 객체마다 다르게 유지되어야 하는 값 -> 인스턴스 변수
- 객체마다 공통된 값 -> 클래스 변수
- 클래스 변수는 객체 생성없이 사용가능
- 인스턴스 변수는 객체 생성 후 사용가능
메서드는
코드의 중복을 방지하고자 어떤 작업을 하는 문장들을 묶어놓은 것
값을 받아서 처리하고, 그 결과를 반환한다.
메서드와 함수는 거의 동일한 개념이다. (메서드 = 반드시 클래스 내에 존재해야 함)
메서드의 장점
- 코드 중복 방지, 코드 재사용 가능, 코드 관리 용이
반복되는 코드를 메서드로 작성.
메서드는 한 가지 기능만 수행하도록 작성하는 것이 좋다.
왜? 의미있는 작업단위로 나눠놔야 코드 재사용이 쉽기 때문.
메서드 작업에 필요한 매개변수는 0~n개 가능
그러나 출력은 0~1개뿐.
여러 값을 출력받고 싶으면 배열을 활용하거나 하나의 객체로 묶어야 한다.
구현부에서 반환된 결과의 타입은 선언부 반환타입과 동일해야 한다.
반환되는 결과가 없으면 타입은 void.
지역변수는 메서드 안에서만 사용되기 때문에 이름이 겹쳐도 괜찮다.
그 어마무시하다는 객체지향을 내가 다시 볼 줄이야...
일단 6장을 계속 반복해서 공부해야 되겠다.
마음을 비우고 지금 당장 이해하지 못한다고 해서 좌절하지 않을 것이다.
우리 팀 이름처럼 언젠간되겠지... 라고 생각하며 살 것이다.
'CODING > 스파르타 내일배움캠프 TIL' 카테고리의 다른 글
14_코트카타_Java 문법 종합반 1,2,3주차_24.12.31(화) (1) | 2024.12.31 |
---|---|
13_코트카타_팀 프로젝트 발표, 피드백, 회고_학습법 특강_자바의 정석 객체지향_24.12.30(월) (0) | 2024.12.30 |
11일차_코트카타 Stream_Firebase_Git 특강 복습_방명록 수정기능 구현_24.12.26(목) (1) | 2024.12.26 |
10일차_코트카타_자바스크립트 자료형_방명록 삭제기능 구현_24.12.24(화) (1) | 2024.12.24 |
TIL 9일차(본 캠프 시작일)_2024.12.23(월) (0) | 2024.12.23 |