Daehoon Lee
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    ###### tags: `project` # 🧮 계산기 ## Ground Rules ### 규칙 - TIL, 일일 회고 작성 시간(매일 22시부터 1시간 작성 진행) - 페어프로그래밍 시간 제한 최대 30분 ### 스크럼 - 오전 10시 디스코드에서 진행 - 금일 진행 사항 공유하기(오늘의 할일) ### 프로젝트 규칙 - 네이밍 준수하기(가이드 라인) - 커밋 메시지 규칙 진행 - 코드에 대한 기록 그때그때 하기 ## 일일 스크럼 ### 🙌 06/12 - 오늘의 컨디션 - hemg: 어제 잠을 못잤는데 훈과의 팀이라 피로감이 날아갔다. - hoon: 좋습니다😆 - MINT: 4인팀 어때요 - zion: - 특이사항 - hemg: 1학기 마지막이 느낌이 좋습니다. - hoon: 햄지랑 팀이라 너무 즐겁습니다. - zion: - 오늘 할 일 - [x] hoon, hemg 계산기 코드 조율하기 - [x] 활동 학습 예습 ### 🙌 06/13 - 오늘의 컨디션 - hemg: 좋음 - hoon: 즐겁습니다🌞 (민트와 함께해서?) - MINT: 헤헤...졸려요 - zion: - 특이사항 - hemg: 없음 살이 안빠짐 - hoon: 민트랑 수다 노닥노닥 - MINT: 훈햄지방 쳐들어가기~! - zion: - 오늘 할 일 - [x] 코드 합치기! STEP1 하기 - [x] STEP2 리팩토링 고민하기 ### 🙌 06/14 - 오늘의 컨디션 - hemg: 오랜만에 잠을 푹자서 좋음 - hoon: 조금 피곤합니다 - MINT: 낮잠 예정~! - zion: - 특이사항 - hemg: 없음 (오이잉?) - hoon: 오후에 운동을 다녀오겠습니다 ㅎㅎ - zion: - 오늘 할 일 - [x] STEP 2 예외 처리 - [x] STEP 2 PR 보내기 ### 🙌 06/15 - 오늘의 컨디션 - hemg: 오늘따라 아침부터 배가 고프다 - hoon: 적당합니다 - zion: - 특이사항 - hemg: 활동학습 내용이 너무 많다 안해! - hoon: 민트랑 수다 떨어요! - zion: - 오늘 할 일 - [x] 활동 학습 예습 - [x] STEP 2 PR 코멘트 답변 - [ ] README 작성 ### 🙌 06/16 - 오늘의 컨디션 - hemg: 눈을뜨니 주식이 20%상승중....(이하생략) 근데 엔화가 폭락와서 매수를 많이했는데 자꾸 떨어지네요... 흠... ㅋㅋㅋ - hoon: 더워요~ - zion: - 특이사항 - hemg: 강남 데이트! 훈과 함께 (민트없음!) - hoon: 오프라인 모각코 및 수료식 참석😆 - zion: - 오늘 할 일 - [x] README 작성 - [x] STEP 2 PR 마무리 # 🧮 계산기 ## 📖 목차 1. [소개](#-소개) 2. [팀원](#-팀원) 3. [타임라인](#-타임라인) 4. [시각화된 프로젝트 구조](#-시각화된-프로젝트-구조) 5. [실행 화면](#-실행-화면) 6. [트러블 슈팅](#-트러블-슈팅) 7. [참고 링크](#-참고-링크) 8. [팀 회고](#-팀-회고) </br> ## 🍀 소개 hoon과 Hemg가 팀으로 기본적인 연산을 수행하는 계산기를 만들었습니다. * 주요 개념: `protocols` , `extensions`, `Error Handling` , `closures` , `advancedoperators`, `inheritance`, `subscripts`, `Generics`, `NumberFormatter` </br> ## 👨‍💻 팀원 | Hemg | hoon | | :--------: | :--------: | | <Img src = "https://user-images.githubusercontent.com/101572902/235090676-acefc28d-a358-486b-b9a6-f9c84c52ae9c.jpeg" width="200" /> |<Img src="https://i.imgur.com/zXoi5OC.jpg" width="200"> |[Github Profile](https://github.com/hemg2) |[Github Profile](https://github.com/Hoon94) </br> ## ⏰ 타임라인 |날짜|내용| |:--:|--| |2023.06.12.| - 서로의 코드 리뷰 <br> - `merge` 할 코드 분류 | |2023.06.13.| - hoon, Hemg 코드 합치기 | |2023.06.14.| - operand 입력 버튼 액션 나누기 <br> - `NumberFormatter` 사용 <br> - 예외 처리 추가 | |2023.06.15.| - 예외 처리 추가 <br> - 불필요한 코드 삭제를 위한 전체 리팩토링| |2023.06.16.| - 가독성을 위해 logical not(!) 연산자 사용 수정 <br> - README 작성 | </br> ## 👀 시각화된 프로젝트 구조 ### Diagram <p align="center"> <img width="800" src="https://cdn.discordapp.com/attachments/1080783877594947597/1119154262077865984/UML_Diagramfinal.jpg"> </p> </br> ## 💻 실행 화면 | AC, CE 버튼 | +/- 버튼 연산 | 정상연산 | |:--------:|:--------:|:--------:| |<img src="https://hackmd.io/_uploads/r1kXttYDn.gif" width="250">|<img src="https://hackmd.io/_uploads/ByFvKKKvn.gif" width="240">|<img src="https://hackmd.io/_uploads/SycOFtYP3.gif" width="250">| | 소수 계산 | 나누기 반올림 | 0 나누기 NaN | |:--------:|:--------:|:--------:| |<img src="https://hackmd.io/_uploads/rkN9tYtDh.gif" width="250">|<img src="https://hackmd.io/_uploads/HJljFKKw2.gif" width="250">|<img src="https://hackmd.io/_uploads/SyRjKKFD2.gif" width="250">| </br> ## 🧨 트러블 슈팅 1️⃣ **`pull request`와 `merge`** <br> - 🔒 **문제점** <br> - 처음 콜라보레이터로 팀원을 등록하고 이전 계산기 1을 기준으로 다른 팀원의 코드를 합치는 방식으로 진행하였습니다. 수정한 내용에 대해 commit을 하고 반영하고 싶은 branch에 PR을 보냄으로써 수정한 내용을 merge 할지에 대한 처리를 할 수 있었습니다. merge를 진행할 때에는 현재 repository의 소유자 또는 콜라보레이터로 등록한 멤버만이 승인을 할 수 있었습니다. merge를 할 때 한 명의 멤버가 PR을 확인하고 이를 승인합니다. 이런 경우 확인하는 멤버의 실수를 통해 불필요한 내용 또는 오류가 merge 될 수 있었습니다. 🔑 **해결방법** <br> - pr을 보내는 branch에 조건들을 설정할 수 있었습니다. merge를 진행할 때 `Require approvals`를 사용하여 승인을 해야하는 리뷰어의 수를 정할 수 있었고 이를 통해 한 명이 merge를 하는 경우에 대한 실수를 여러명의 검증을 통해 줄일수 있었습니다. <br> 2️⃣ **예외 처리** <br> - 🔒 **문제점** <br> - 계산기를 다양한 경우에 대해 테스트하던 중 많은 엣지 케이스들이 존재하였습니다. 🔑 **해결방법** <br> - 문제가 발생한 케이스에 대해 하나씩 테스트를 진행하며 수정하였습니다. 대표적으로 다음과 같은 경우에 대한 예외 처리들을 진행하였습니다. 1. 부호(+/-)를 붙일 때 소수 부분 처리 (before: -2.3 -> -2, after: -2.3 -> -2.3) 2. 처음 0일 때 00은 입력받지 않는다 (before: 0 -> 00, after: 0 -> 0) 3. 입력창에서 소수점일 때 뒤에 0, 00 추가 (before: 2. -> 2, after: 2. -> 2.0 or 2.00) 4. numberformatter를 사용한 쉼표 표현 (before: 1000, after: 1,000) 5. "음수 × 0"이면 결괏값은 부호가 없는 "0" (before: -9 * 0 -> -0, after: -9 * 0 -> 0) 6. 소수 부분에서 필요 없는 0 처리 (before: 2.1200 -> 2.1200, after: 2.1200 -> 2.12) 7. 나누기 0인 경우 결과가 NaN이 나오고 AC, CE 버튼 외에는 전부 사용 불가 8. 결과를 출력하면 AC, CE, +/-, 사칙연산 외에는 전부 사용 불가 9. 실수에서 소수점을 기준으로 자연수에는 "," 처리 10. 최대 입력받는 자릿수는 16자리로 제한 <br> 3️⃣ **중복 코드** <br> - 🔒 **문제점** <br> - `touchUpOperandButton`에서 너무 많은 조건문을 사용하여 이를 줄이고자 기능을 분리하기 위해 `0`, `00` 버튼을 새로운 액션으로 진행했습니다. 그래서 `touchUpZeroButton`과 `touchUpDoubleZeroButton`을 새로 추가하였습니다. 하지만 이 두 함수는 내부 구현에서 큰 차이가 없었습니다. ```swift let realNumber = (currentOperand + zero).split(with: ".") if realNumber.count == 2 { operandLabel.text = (numberFormatter.string(for: Double(realNumber[0])) ?? "0") + "." + realNumber[1] } else { operandLabel.text = numberFormatter.string(from: NSNumber(value: newOperand)) } ``` 🔑 **해결방법** <br> - 네이밍을 유지하여 각각의 메서드에 대한 동작을 확실히 표현하며 내부 로직만을 메서드로 분리하였습니다. 내부 로직을 메서드로 분리함으로써 다른 곳에서도 재활용성을 높여 중복된 코드를 줄일 수 있었습니다. ```swift @IBAction func touchUpZeroButton(_ sender: UIButton) { inputZero(1) } @IBAction func touchUpDoubleZeroButton(_ sender: UIButton) { inputZero(2) } private func inputZero(_ count: Int) { guard validateOperandInput(with: count), currentOperand != "0" else { isPlaceholder = false return } let newOperand = currentOperand + String(repeating: "0", count: count) let realNumber = newOperand.split(with: ".") guard let numberValue = Double(realNumber[0]), let integerNumber = numberFormatter.string(from: NSNumber(value: numberValue)) else { return } if realNumber.count == 1 { operandLabel.text = integerNumber } else { operandLabel.text = integerNumber + "." + String(realNumber[1]) } } private func validateOperandInput(with textCount: Int) -> Bool { guard !isResult else { return false } return currentOperand.count + textCount < 16 } ``` <br> ## 📚 참고 링크 - [🍎Apple Docs: protocols](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/protocols/) - [🍎Apple Docs: extensions](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/extensions/) - [🍎Apple Docs: Error Handling](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/errorhandling/) - [🍎Apple Docs: closures](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/closures/) - [🍎Apple Docs: advancedoperators](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/advancedoperators/) - [🍎Apple Docs: inheritance](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/inheritance/) - [🍎Apple Docs: subscripts](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/subscripts/) - [🍎Apple Docs: API Design Guidelines](https://www.swift.org/documentation/api-design-guidelines/) - [🍎Apple Docs: NumberFormatter](https://developer.apple.com/documentation/foundation/numberformatter) - [🍎Apple Docs: Generics](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/generics/) </br> ## 👥 팀 회고 - [팀 회고 링크](https://github.com/Hoon94/ios-calculator-app/blob/Calculator2_step2/%ED%8C%80%ED%9A%8C%EA%B3%A0.md) # 팀 회고 ## 우리팀이 잘한 점 - 서로의 코드를 비교하여 더 좋은 방식으로 개선하도록 노력하였습니다. - 공부하는 시간을 충분히 확보하여 단순히 동작만을 하는 것이 아닌 이해를 바탕으로 코드를 작성하였습니다. ## 서로에게 좋았던 점 피드백 - to Hemg - 서로 코드를 설명하고 각각의 장단점을 비교하며 더 나은 코드로 개선하기 위해 고민하는 모습이 좋았습니다. - to hoon - 어떤 문제에 직면을 했을 때에도 냉정함을 잃지 않고 차분하게 문제를 파악하고 해결하는 그 모습에 반했습니다. ## 서로에게 하고싶은 말 - to Hemg - 오랜만에 햄지와 다시 한번 팀을 해서 좋았습니다. 다음에 저희는 또 만날 수 있을 거예요. 삼세번😆 - to hoon - 다시 못 만날 거라 생각했는데 다시 만나서 너무 좋았습니다 5일간 프로젝트를 진행했는데 너무 금방 끝나버린 느낌이 있네요. 삼세번은 해야지요? 한 번 더 팀이 되길 바라겠습니다. # STEP 1 - 안녕하세요 건디! 1학기 마지막 리뷰를 받게 된 Hoon, Hemg 입니다. 건디도 서포터즈로써 마지막 리뷰이겠네요! 잘 부탁드립니다! - Hoon, Hemg -> 둘 다 `Linked List` 로 구현을 해서 `Linked List` 설정으로 코드를 합쳤습니다. - 추가적으로 로직에 대한 부분 또한 큰 차이가 없었습니다! 🫢 ## 고민되었던 점 ### PR과 merge 하는 방법 - 처음 콜라보레이터로 팀원을 등록하고 이전 계산기 1을 기준으로 다른 팀원의 코드를 합치는 방식으로 진행하였습니다. 수정한 내용에 대해 commit을 하고 반영하고 싶은 branch에 PR을 보냄으로써 수정한 내용을 merge 할지에 대한 처리를 할 수 있었습니다. 여기서 branch에 merge 하는 과정에 대한 조건들을 설정할 수 있었고 진행 중에 `Require approvals`를 사용하여 PR을 작성한 팀원이 아닌 다른 팀원이 리뷰어로써 approve를 해줌으로써 merge가 가능하도록 하였습니다. ### 리팩토링할 내용 - STEP 2에서 다음과 같은 부분들을 리팩토링해보기로 정하였습니다. - NumberFormatter - 예외처리 - 스크롤뷰 indicators 사용 - +/- 음수 처리(-2.0 -> -2) 안녕하세요 건디()👋 계산기 STEP 2 PR 남깁니다. 벌써 1학기 마지막 PR이네요🤣🤣🤣 마지막까지 열심히 달려보겠습니다. 감사합니다.🙇 # STEP 2 ## 고민되었던 점 ### 예외 처리 - 다음과 같은 경우에 대한 예외 처리들을 진행하였습니다. 1. 부호(+/-)를 붙일 때 소수 부분 처리 (before: -2.3 -> -2, after: -2.3 -> -2.3) 2. 처음 0일 때 00은 입력받지 않는다 (before: 0 -> 00, after: 0 -> 0) 3. 소수점일 때 뒤에 0, 00 추가 (before: 2. -> 2, after: 2. -> 2.0 or 2.00) 4. numberformatter 쉼표 처리 (before: 1000, after: 1,000) 5. "음수 × 0"이면 0이 나온다 (before: -9 * 0 -> -0, after: -9 * 0 -> 0) 6. 소수점 필요 없는 0 처리 (before: 2.1200 -> 2.1200, after: 2.1200 -> 2.12) 7. 나누기 0인 경우 결과가 NaN이 나오고 AC, CE 버튼 외에는 전부 사용 불가 8. 결과를 출력하면 AC, CE, +/-, 사칙연산 외에는 전부 사용 불가 9. 실수에서 소수점을 기준으로 자연수에는 "," 처리 10. 최대 입력받는 자릿수는 15자리로 제한 ## 해결 하지 못한 점 ### 20개의 자릿수에 대한 설정 - 20개 이하의 자릿수를 표현하기가 어려웠습니다. `Decimal`를 사용하여 나타낼 수 있을 거라 생각했습니다. 기존에 `Double`을 가지고 있다가 `Double` -> `Decimal`로 나타내더라도 자릿수의 한계가 있어서 방법이 아닌 것 같았습니다. 그래서 초기 타입 자체를 `Decimal`로 해야지만 가능하다고 생각했습니다. 그렇게 되면 전체적으로 `Double` 타입을 `Decimal` 타입으로 변경해야 하는 점.. (주어진 `UML을 어기되네요...) 전체적인 수정이 진행되는데 이렇게 해서 진행을 해야 할까요? 아니면 다른 방법이 있다면 그 방법을 알 수 있을까요? 좋은 방안이 떠오르지 않습니다.😭 ## 조언을 얻고 싶은 점 ### 코드 중복 - `touchUpOperandButton`에서 너무 많은 조건문을 사용하여 이를 줄이고자 기능을 분리하기 위해 `0`, `00` 버튼을 따로 빼서 진행했습니다. 그래서 `touchUpZeroButton`과 `touchUpDoubleZeroButton`을 추가하였습니다. 하지만 이 두 함수는 내부 구현에서 큰 차이가 없었습니다. 이러한 경우 여기서 하나의 함수를 만들어서 내부 구현에 재사용 하는 것이 좋을까요? `0`, `00` 버튼을 하나로 통합하는 방법도 생각했지만 두 버튼 동작을 명확하게 구분 짓는 것도 가독성 면에서 좋다고 생각했습니다. 어떤 방식으로 진행하면 더 좋을까요? ```swift let realNumber = (currentOperand + zero).split(with: ".") if realNumber.count == 2 { operandLabel.text = (numberFormatter.string(for: Double(realNumber[0])) ?? "0") + "." + realNumber[1] } else { operandLabel.text = numberFormatter.string(from: NSNumber(value: newOperand)) } ``` - 계산기의 동작에 대한 여러 예외 처리를 진행하다 보니 하나씩 해결할 때마다 조건문이 계속 발생하였습니다. 이렇게 만들어진 조건문들은 중복되는 경우도 많았습니다. 조건문을 사용하기보다는 기능을 분리하거나 다른 방법을 통해 줄이는 게 좋을까요? 계산기의 경우 현재 많은 조건문이 있는데 이러한 조건문은 어떤 방식으로 줄여볼 수 있을까요? - 예외처리 1. 부호(+/-)를 붙일 때 소수 부분 처리 (before: -2.3 -> -2, after: -2.3 -> -2.3) 2. 처음 0일 때 00은 입력받지 않는다 (before: 0 -> 00, after: 0 -> 0) 3. 소수점일 때 뒤에 0, 00 추가 (before: 2. -> 2, after: 2. -> 2.0 or 2.00) 4. numberformatter 쉼표 처리 (before: 1000, after: 1,000) 5. "음수 × 0"이면 0이 나온다 (before: -9 * 0 -> -0, after: -9 * 0 -> 0) 6. 소수점 필요없는 0 처리 (before: 2.1200 -> 2.1200, after: 2.1200 -> 2.12) 7. 나누기 0인 경우 결과가 NaN이 나오고 AC, CE 버튼 외에는 전부 사용 불가 8. 결과를 출력하면 AC, CE, +/-, 사칙연산 외에는 전부 사용 불가 9. 실수에서 소수점을 기준으로 자연수에는 "," 처리 10. 최대 입력받는 자릿수는 15자리로 제한

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully