ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Chapter 06-2~06-4
    Do it! 점프 투 파이썬 2022. 6. 8. 23:03

    3과 5의 배수 합하기

    자, 다음 문제를 어떻게 풀면 좋을지 생각해 보자.

    10 미만의 자연수에서 3과 5의 배수를 구하면 3, 5, 6, 9이다. 이들의 총합은 23이다.
    1000 미만의 자연수에서 3의 배수와 5의 배수의 총합을 구하라.
    • 입력받는 값은? 1부터 999까지(1000 미만의 자연수)
    • 출력하는 값은? 3의 배수와 5의 배수의 총합
    • 생각해 볼 것은? 하나. 3의 배수와 5의 배수는 어떻게 찾지? 둘. 3의 배수와 5의 배수가 겹칠 때는 어떻게 하지?

    이 문제를 풀기 위한 중요 포인트는 두 가지이다. 한 가지는 1000 미만의 자연수를 구하는 방법이고 또 다른 한 가지는 3과 5의 배수를 구하는 것이다. 이 두가지만 해결되면 문제는 쉽게 해결될 것으로 보인다.

     

    1. 먼저 1000 미만의 자연수는 어떻게 구할 수 있을지 생각해 보자. 여러 가지 방법이 떠오를 것이다. 다음과 같이 변수에 초깃값 1을 준 후 루프를 돌리며 1씩 증가시켜서 999까지 진행하는 방법이 가장 일반적인 방법일 것이다.

    n = 1
    while n < 1000:
        print(n)
        n += 1

     

    또는 다음과 같이 좀 더 파이썬다운 range 함수를 사용할 수도 있다.

    for n in range(1, 1000):
        print(n)

    두 가지 예 모두 실행하면 1부터 999까지 출력하는 것을 확인할 수 있다.

     

    2. 1000까지의 자연수를 차례로 구하는 방법을 알았으니 3과 5의 배수를 구하는 방법을 알아보자. 1000 미만의 자연수 중 3의 배수는 다음과 같이 증가할 것이다.

    3, 6, 9, 12, 15, 18, ..., 999

     

    그렇다면 1부터 1000까지 수가 진행되는 동안 그 수가 3의 배수인지는 어떻게 알 수 있을까? 1부터 1000까지의 수 중 3으로 나우었을 때 나우어떨어지는 경우, 즉 3으로 나누었을 때 나머지가 0인 경우가 바로 3의 배수이다. 따라서 다음과 같이 % 연산자를 사용하면 3의 배수를 쉽게 찾을 수 있다.

    for n in range(1, 1000):
        if n % 3 == 0:
            print(n)

    그렇다면 5의 배수는 n % 5가 0이 되는 수로 구할 수 있을 것이다.

     

    3. 이러한 내용을 바탕으로 만든 최종 풀이는 다음과 같다.

    result = 0
    for n in range(1, 1000):   <- 1부터 999까지 n에 대입하며 반복
        if n % 3 == 0 or n % 5 == 0:   <- n을 3으로 나눈 나머지가 0이거나 n을 5로 나눈 나머지가 0이라면
            result += n
    print(result)

    3과 5의 배수에 해당하는 수를 result 변수에 계속해서 더해 주었다.

     

    이 문제에는 한 가지 함정이 있는데 3으로도 5로도 나누어지는 15와 같은 수를 이중으로 더해서는 안 된다는 점이다. 따라서 15와 같이 3의 배수도 되고 5의 배수도 되는 값이 이중으로 더해지지 않기 위해 or 연산자를 사용하였다.

     

    다음 예는 15와 같은 수를 이중으로 더하여 잘못된 결과를 출력하는 잘못된 풀이이다.

    [잘못된 풀이]

    result = 0
    for n in range(1, 1000):
        if n % 3 == 0:
            result += n
        if n % 5 == 0:
            result += n
    print(result)

     

     

    * 코딩 연습을 할 수 있는 사이트

    이 문제는 코딩 연습을 할 수 있는 '프로젝트 오일러'라는 사이트의 첫 번째 문제이다. 이 사이트는 첫 번째 문제부터 차례대로 풀 수 있으며 본인이 작성한 답이 맞는지 즉시 확인할 수도 있다.

    프로젝트 오일러(projecteuler.net/archives)

     

     

     

     

    게시판 페이징하기

    A 씨는 게시판 프로그램을 작성하고 있다. 그런데 게시물의 총 건수와 한 페이지에 보여 줄 게시물 수를 입력으로 주었을 때 총 페이지 수를 출력하는 프로그램이 필요하다고 한다.

    • 함수 이름은? getTotalPage
    • 입력받는 값은? 게시물의 총 건수(m), 한 페이지에 보여 줄  게시물 수(n)
    • 출력하는 값은? 총 페이지 수

    A씨가 필요한 프로그램을 만들기 위해 입력값과 결괏값이 어떻게 나와야 하는지 먼저 살펴보자. 게시물의 총 건수가 5이고 한 페이지에서 보여 줄 게시물 수가 10이면 총 페이지 수는 당연히 1이 된다. 만약 게시물의 총 건수가 15이고 한 페이지에서 보여 줄 게시물 수가 10이라면 총 페이지 수는 2가 될 것이다.

    게시물의 총 건수(m) 페이지당 보여 줄 게시물 수(n) 총 페이지 수
    5 10 1
    15 10 2
    25 10 3
    30 10 3

    이 문제는 게시판 프로그램을 만들 때 가장 처음 마주치는 난관이라고 할 수 있는 총 페이지 수를 구하는 문제이다. 사실 실제 업무에서 사용하는 페이징 기술은 훨씬 복잡한데 여기에서는 그중 가장 간단한 총 페이지 수를 구하는 방법에 대해서만 알아보겠다.

     

    1. 다음과 같이 총 건수(m)를 한 페이지에 보여 줄 게시물 수(n)로 나누고 1을 더하면 총 페이지 수를 얻을 수 있다.

    총 페이지 수 = (총 건수 / 한 페이지당 보여 줄 건수) + 1

     

    2. 이러한 공식을 적용했을 경우 총 페이지 수가 표의 값처럼 구해지는지 확인해 보자(m을 n으로 나눌 때 소수점 아래 자리를 버리기 위해 / 대신 // 연산자를 사용하였다.)

    def getTotalPage(m, n):
        return m // n + 1

    print(getTotalPage(5, 10))   <- 첫 번째 케이스, 1이 출력됨
    print(getTotalPage(15, 10))   <- 두 번째 케이스, 2가 출력됨
    print(getTotalPage(25, 10))   <- 세 번째 케이스, 3이 출력됨
    print(getTotalPage(30, 10))   <- 네 번째 케이스, 3이 출력되어야 하는데 4가 출력됨

    첫 번째, 두 번째, 세 번째 케이스는 공식에 맞게 결과가 출력된다. 하지만 네 번째 케이스는 총 건수가 30이고 한 페이지에 보여 줄 건수가 10인데 4가 출력되어 실패해 버렸다. 잘 생각해 보자. 총 건수가 30이고 한 페이지에 보여 줄 건수가 10이라면 당연히 총 페이지 수는 3이 되어야 한다.

     

    3. 실패 케이스는 총 게시물 수와 한 페이지에 보여 줄 게시물 수를 나눈 나머지 값이 0이 될 때 발생함을 유추할 수 있을 것이다. 이 실패 케이스를 해결하려면 다음과 같이 코드를 변경해야 한다.

    def getTotalPage(m, n):
        if m % n == 0:
            return m // n
        else:
            return m // n + 1

    print(getTotalPage(5, 10))
    print(getTotalPage(15, 10))
    print(getTotalPage(25, 10))
    print(getTotalPage(30, 10))

    나누었을 때 나머지가 0인 경우는 나누기의 몫만 돌려주고 그 이외의 경우에는 1을 더하여 돌려주도록 변경했다.

    프로그램을 실행해 보면 모든 케이스가 원하던 결과를 출력함을 확인할 수 있다.

     

     

     

     

    간단한 메모장 만들기

    원하는 메모를 파일에 저장하고 추가 및 조회가 가능한 간단한 메모장을 만들어 보자.

    • 필요한 기능은? 메모 추가하기, 메모 조회하기
    • 입력받는 값은? 메모 내용, 프로그램 실행 옵션
    • 출력하는 값은? memo.txt

    가장 먼저 해야 할 일은 메모를 추가하는 것이다. 다음 명령을 실행했을 때 메모를 추가할 수 있도록 만들어 보자.

    python memo.py -a "Life is too short"

    memo.py는 우리가 작성할 파이썬 프로그램 이름이다. -a는 이 프로그램의 실행 옵션이고 "Life is too short"는 추가할 메모 내용이 된다.

     

    1. 우선 다음과 같이 입력으로 받은 옵션과 메모를 출력하는 코드를 작성해 보자.

    # C:/doit/memo.py
    import sys

    option = sys.argv[1]
    memo = sys.argv[2]

    print(option)
    print(memo)

    sys.argv는 프로그램을 실행할 때 입력된 값을 읽어 들일 수 있는 파이썬 라이브러리이다. sys.argv[0]는 입력받은 값 중에서 파이썬 프로그램 이름인 memo.py이므로 우리가 만들려는 기능에는 필요 없는 값이다. 그리고 순서대로 sys.argv[1]은 프로그램 실행 옵션 값이 되고 sys.argv[2]는 메모 내용이 된다.

     

    2. memo.py를 작성했다면 다음 명령을 수행해 보자.

    C:\doit>python memo.py -a "Life is too short"
    -a
    Life is too short

    입력으로 전달한 옵션과 메모 내용이 그대로 출력되는 것을 확인할 수 있다.

     

    3. 이제 입력으로 받은 메모를 파일에 쓰도록 코드를 변경해 보자.

    # C:/doit/memo.py
    import sys

    option = sys.argv[1]

    if option == '-a':
        memo = sys.argv[2]
        f = open('memo.txt', 'a')
        f.write(memo)
        f.write('\n')
        f.close( )

    옵션이 -a인 경우에만 memo 값을 읽어 memo.txt 파일에 그 값을 쓰도록 코드를 작성했다. 여기에서 메모는 항상 새로운 내용이 작성되는 것이 아니라 한 줄씩 추가되어야 하므로 파일 열기 모드를 a로 했다. 그리고 메모를 추가할 때마다 다음 줄에 저장되도록 줄바꿈 문자(\n)도 추가로 파일에 쓰게 했다.

     

    4. 이제 다음과 같은 명령을 수행해 보자.

    C:\doit>python memo.py -a "Life is too short"
    C:\doit>python memo.py -a "You need python"

     

    그리고 파일에 정상적으로 메모가 기입되었는지 다음과 같이 확인해 보자.

    C:\doit>type memo.txt
    Life is too short
    You need python

    추가한 메모가 정상적으로 저장된 것을 볼 수 있다.

     

    5. 이번에는 작성한 메모를 출력하는 부분을 만들 차례이다. 메모 출력은 다음과 같이 동작하도록 만들어 보자.

    python memo.py -v

    메모 추가는 -a 옵션을 사용하고 메모 출력은 -v 옵션을 사용한다.

     

    이제 메모 출력을 위해 다음과 같이 코드를 변경해 보자.

    # C:/doit/memo.py
    import sys

    option = sys.argv[1]

    if option == '-a':
        memo = sys.argv[2]
        f = open('memo.txt', 'a')
        f.write(memo)
        f.write('\n')
        f.close( )
    elif option == '-v':
        f = open('memo.txt')
        memo = f.read( )
        f.close( )
        print(memo)

    옵션으로 -v가 들어온 경우 memo.txt 파일을 읽어서 출력한다.

     

    6. 코드를 수정한 후 다음과 같은 명령을 수행해 보자.

    C:\doit>python memo.py -v
    Life is too short
    You need python

    입력한 메모가 그대로 출력되는 것을 확인할 수 있다.

     

     

     

     

     

    출처 : "점프 투 파이썬"

Designed by Tistory.