メインコンテンツまでスキップ

프로그래밍 실습

프로그래밍 실습

AI 디지털교과서 플랫폼은 별도의 환경 설치 없이 학생들이 직접 코드를 작성하고 실행할 수 있는 프로그래밍 실습을 지원합니다.

특히 실행 버튼을 눌러 학생이 스스로 작성한 코드를 직접 실행해 볼 수 있고, 제출 버튼을 눌러 문제에서 원하는 대로 올바른 코드를 작성했는지 여부를 즉시 확인할 수 있습니다.

1️⃣ 프로그래밍 실습 문제의 구성

AI 디지털교과서 프로그래밍 실습은 크게 아래의 네 가지로 구성되어 있습니다.

  1. 실습 환경
  2. 문제 설명과 지시 사항
  3. 스켈레톤 코드(실습 문제)
  4. 채점 코드(실행/채점 파일)

위의 항목을 설정하고 작성하여 학생들에게 유익한 프로그래밍 실습을 만들어봅시다.

구성 항목세부 설명
실습 환경실습 문제를 제작하기 위한 실습의 기반 환경입니다.
문제 설명과 지시 사항실습의 목표와 해당 실습에서 해결해야 할 문제에 대한 자세한 설명을 작성할 수 있습니다.
스켈레톤 코드 (실습 문제)학생들이 코드를 입력할 때 도움을 줄 수 있는 기본 코드입니다.
채점 코드 (실행/채점 파일)학생들이 작성한 코드를 실행하고 채점하기 위한 코드입니다.

2️⃣ 프로그래밍 실습 추가하기

  1. 수업 목록에서 실습을 추가하려는 수업을 클릭합니다.


  1. 수업 자료 추가 버튼을 클릭합니다.


  1. 새로 만들기 선택 후, 추가할 자료 유형 중 프로그래밍 실습다음 버튼을 클릭합니다.


  1. *필수 항목인 자료 제목과 실습 유형, 제출 버튼 옵션을 아래 내용을 참고하여 설정 후 저장 버튼을 클릭합니다.

설정세부 설명
자료 제목수업 목록 및 실습 하단에 보이는 자료 제목입니다.
실습 유형

실습의 유형을 설정합니다.

  • CLI 프로그래밍
    : Python, C/C++과 같은 Command Line Interface의 약어로 텍스트 기반의 코드 입력을 할 수 있는 실습 환경입니다.
  • 아두이노
    : 아두이노 보드를 컴퓨터와 연결하여 AI디지털교과서에서 프로그래밍할 수 있는 실습 환경입니다.
  • 스크래치
    : 스크래치 블록 프로그래밍을 할 수 있는 실습 환경입니다.
  • 다중 언어 실습
    : C, C++, Java, Python 3, Javascript, Rust, Go, Ruby, Swift, Kotlin, C#, F#, Scala, Lua, PHP 총 15가지의 언어를 학생 선택에 따라 바꾸면서 실습할 수 있습니다. 채점은 STDIO Grader 에 한정됩니다.
  • 엔트리
    : 블록 코딩을 통해 게임, 애니메이션 등을 제작할 수 있는 실습 환경입니다.
  • 마이크로비트
    : 마이크로비트 보드를 컴퓨터와 연결하여 센서 및 LED를 활용한 프로그래밍을 할 수 있는 실습 환경입니다.
제출 버튼학생이 작성한 코드를 채점하기 위해 제출 버튼의 사용 여부를 설정합니다.

자료 추가 시 설정한 내용은 실습을 만든 이후에도

수업 자료 수정 버튼을 클릭하여 탭에서 수정할 수 있습니다.


3️⃣ 실습 환경 설정하기

실습 유형에 따른 환경 설정 방법은 하단의 링크들을 통해 확인할 수 있습니다.


4️⃣ 문제 설명, 지시 사항 및 해설

프로그래밍 실습 문제에 대한 설명과 지시 사항 및 해설을 작성할 수 있습니다.

  1. 우측 상단에 있는 수업 자료 수정 아이콘을 클릭합니다.


  1. 왼쪽 패널의 설명, 지시 사항 항목의 에디터에 문제와 관련된 글을 작성하고 이미지를 삽입할 수 있습니다.

  • 코드 블럭을 만들면 해당 내용을 복사할 수 있도록 Copy 버튼이 생겨 학생들이 쉽게 코드 블럭 안의 내용을 복사하여 이용할 수 있습니다.
  • 자주 사용하는 Markdown 문법은 아래의 내용을 참고하실 수 있습니다.
  • # 자주 사용하는 Markdown 문법
    bold : **텍스트**
    bullet point : -텍스트
    글자 크기 : #텍스트 > ##텍스트 > ###텍스트
    코드 블럭 : `텍스트`
    여러 줄 코드 블럭 : ```enter 텍스트 enter```

  1. 해설 탭은 선생님들께만 보이는 기능으로 학생들에게는 표시되지 않습니다.


  1. 문제의 설명, 지시사항해설을 작성한 후에는 우측 하단의 저장 버튼을 클릭하여 내용을 저장합니다.

  • 해당 화면은 CLI 프로그래밍을 기준으로 엔트리와 마이크로비트의 저장 방법은 해당 페이지에서 있습니다.

1) 스켈레톤 코드 작성하기

적절한 스켈레톤 코드는 학생들의 코딩을 더 쉽게 해줍니다.

학생들이 코드 작성을 쉽게 시작할 수 있도록 코드 에디터에 적절한 스켈레톤 코드를 미리 작성해 둘 수 있습니다.

  1. 우측 상단의 수업 자료 수정 버튼을 클릭합니다.


  1. 우측 상단의 실습 문제 작성 탭 실습 파일 목록에서 main.* 파일을 선택합니다.

템플릿을 사용하실 경우 main.py에 스켈레톤 코드가 작성되어 있습니다.


  1. 학생들의 코드 작성을 돕는 적절한 스켈레톤 코드를 작성합니다.


  1. 실습 페이지에 접속했을 때 기본적으로 학생에게 보여주고자 하는 스켈레톤 파일을 설정한 후 저장 버튼을 눌러 코드를 저장합니다.

▶️ 기본 스켈레톤 파일 설정하기

학생들이 해당 실습 페이지에 들어갔을 때 기본적으로 볼 수 있는 파일을 설정하기 위한 방법입니다.

  1. 우측 상단의 수업 자료 수정 버튼을 클릭합니다.


  1. 실습 문제 작성 탭에서 파일 목록 하단의 스켈레톤 파일 설정을 클릭합니다.


  1. 기본적으로 보이고 싶은 파일의 왼쪽 체크 박스를 순서대로 클릭한 후, 다시 하단 설정 버튼을 클릭합니다.


  1. 우측 하단 저장 버튼을 클릭합니다.

▶️ 기본 스켈레톤 파일 설정 더 알아보기

  1. 파일을 클릭하여 폴더 내부에 위치한 파일들을 확인하실 수 있습니다.
  2. 파일을 읽기 전용으로 만들려면 더 보기 옵션 클릭 후 읽기 전용버튼을 눌러줍니다.


  1. 학생에게 해당 파일을 보이지 않게 설정하려면 체크박스 해제 후 더보기 옵션 클릭 ▶️ 파일숨기기를 클릭합니다.


2) 코드 파일 추가 및 삭제하기

스켈레톤 코드를 작성할 main. py 파일뿐만 아니라 다양한 코드 파일을 추가하고 삭제할 수 있습니다.

▶️ 코드 파일 추가하기

  1. 우측 상단 '실습 문제 작성' 탭에서 파일 목록 상단의 '+' 아이콘을 클릭합니다.


  1. 새롭게 생성된 코드 파일의 이름과 확장자를 설정합니다. 예시) model.py, model.R


  1. 우측 하단 '저장' 버튼을 클릭합니다.

▶️ 코드 파일 삭제하기

  1. 우측 상단에 있는 수업 자료 수정 아이콘을 클릭합니다.


  1. '실습 문제 작성' 탭에서 삭제하고자 하는 파일 우측의 더 보기(:) 클릭 후 나오는 옵션 중 삭제를 클릭합니다.


  1. 우측 하단 '저장' 버튼을 클릭합니다.


5️⃣ 프로그래밍 실습 삭제하기

  1. 삭제하고자 하는 실습 왼쪽의 체크 박스를 클릭합니다.

  1. 상단에 나타나는 '삭제' 버튼을 클릭합니다.


  1. 이후 나타나는 알림창의 '확인' 버튼을 클릭합니다.

삭제 이후에는 복원이 불가하기 때문에 삭제는 신중하게 결정해 주십시오.


6️⃣ 채점하기

AI 디지털교과서에서는 다양한 방식으로 상황에 맞게 채점을 진행할 수 있습니다.

아래 각 방법의 장단점을 보시고 가장 잘 맞는 방식을 사용하여 문제별로 사용하시면 됩니다.

1) STDIO 표준 입출력 기반 채점

장점: 알고리즘과 같은 입력과 출력이 있는 실습에 적절하며, 채점 기능을 설정하는 데 소요되는 시간이 짧습니다.

단점: 특정한 입력과 출력이 정해져 있는 문제에서만 사용할 수 있습니다.

간단한 채점을 위해 표준 입력/출력을 기반으로 한 채점 코드를 작성할 수 있습니다.

자동으로 코드가 생성됩니다.

입력/출력 채점은 입력값에 대해 특정 값이 출력되는지 여부를 채점하는 방법입니다.

  1. 우측 상단에 있는 수업 자료 수정 아이콘을 클릭합니다.


  1. 실습 수정 페이지 상단의 실행/채점 파일 작성 탭을 클릭합니다.


  1. 하단 STDIO 채점 코드 구성하기 버튼을 클릭합니다.


  1. + 버튼을 눌러 원하는 입출력 채점 방식에 따라 테스트 케이스와 실행 제한 시간, 점수를 설정합니다.


  1. 아래 채점 메시지 작성을 클릭하여 정답/오답 시 출력되는 메시지를 작성합니다.


  1. 오른쪽 아래의 저장 버튼을 클릭합니다.

  • STDOUT 출력값이 같음 : 설정한 문자열과 학생이 작성한 코드의 출력값이 완전히 동일한 경우 정답으로 채점
  • STDOUT 출력값에 문자열이 포함 : 학생이 작성한 코드의 출력값에 설정한 문자열이 포함될 경우 정답으로 채점
  • STDOUT 출력값에 문자열이 포함되지 않을 경우 : 학생이 작성한 코드의 출력값에 설정한 문자열이 포함되지 않을 경우 정답으로 채점
  • STDOUT 출력값과 정규표현식이 일치: 학생이 작성한 코드 출력값에 설정한 정규표현식이 일치할 경우 정답으로 채점
  • STDOUT 출력값과 정규표현식이 일치하지 않을 경우: 학생이 작성한 코드의 출력값에 설정한 정규표현식이 일치하지 않을 경우 정답으로 채점

이미 채점 코드가 존재한다면 입력/출력 채점 코드로 덮어 씌워집니다.

2) 채점 스크립트

장점: 다양한 케이스를 고려한 채점이 가능합니다.

단점: 실습 언어에 알맞은 채점 코드 작성이 필요합니다.

AI 디지털교과서에서는 코드를 채점할 때 grader.*를 사용합니다.
표준 입/출력 방식, 코드 비교를 이용한 채점 방식 등 다양한 채점 방법을 이용할 수 있습니다.

▶️ 채점 코드 작성하기

.elice 폴더의 grader.* 파일은 학생이 작성한 코드를 채점할 수 있는 답안 코드를 작성하는 곳입니다.

(.elice는 엘리스가 제공하는 예시로 교과서 마다 폴더명이 다를 수 있습니다.)

  1. 상단의 실행/채점 파일 작성을 클릭하십시오.


  1. 좌측 상단의 코드 뷰어로 전환을 클릭하십시오.


  1. .elice를 클릭하여 하위 폴더를 확인할 수 있습니다.

이곳에 채점을 위한 코드를 작성하세요. 각 파일의 구성은 다음과 같습니다.

  • grader.py : 실제 채점 스크립트를 작성하는 파일
  • grader.sh : 학생이 제출 버튼을 눌렀을 때 실행되는 bash shell script
  • grader_aidt_utils.py : 제출 환경에서 동작 즉, 채점 시 사용할 aidt utils의 모음
  • runner.sh : 학생이 실행 버튼을 눌렀을 때 실행되는 bash shell script

▶️ 채점하기

학생이 에디터에서 코드를 작성한 후 제출 버튼을 누르면 선생님이 grader.*에 작성해 놓은 답안 코드에 의해서 학생의 코드가 자동 채점됩니다.

3) 수동 채점

장점: 학생이 작성한 코드를 직접 확인하여 점수를 배부할 수 있습니다.

단점: 모든 학생의 코드를 살펴본 후 점수를 부여해 주어야 함으로 채점에 많은 시간 소요됩니다.

학생이 제출한 코드를 보고 수동으로 점수를 부여할 수 있습니다.

  1. 실습 화면 좌측 상단의 튜터링 아이콘을 클릭합니다.


  1. 점수를 줄 학생을 검색 및 선택하면 학생의 코드 에디터를 볼 수 있습니다.


  1. 우측 상단 최종 점수 칸의 📝버튼을 클릭합니다.


  1. 아래 화면에서 학생이 받은 점수에서 가감할 점수를 입력하여, 학생이 받을 점수를 설정한 후 적용 버튼을 누릅니다.

수동 점수를 주기 위해서는 학생이 한 번 이상 제출한 이력이 있어야 합니다.


*️⃣ Python 스크립트 기반 채점

grader.py 파일을 수정하여 채점 스크립트를 작성하는 방법에 대해 알아봅시다.

grader.sh은 학생이 제출 버튼을 눌렀을 때 실행되며,
grader.sh에서 grader.py를 실행하여 채점을 시작합니다.

grader.py를 작성하기 위해 자주 사용되는 aidt_utils.py의 함수들에 대해 일반적인 형식과 함께 안내해 드리겠습니다.

  • secure_send_grader(): 터미널을 통해 사용자에게 메세지 출력
  • secure_send_score(): 실습의 최종 점수 설정
from grader_aidt_utils import AIDTUtils
aidt_utils = AIDTUtils()
# aidt_utils 가져오고 초기화합니다.
aidt_utils.secure_init()

# 채점을 진행합니다.
try:
# 학습자의 터미널 창에 문자열을 전송합니다.
aidt_utils.secure_send_grader('문자열')
# 학습자의 실습 점수를 전송합니다. 100점 획득 시, 정답으로 확인됩니다.
aidt_utils.secure_send_score(100)

# 채점 진행과정에서 오류가 발생하는 경우
except Exception:
# 실습 점수를 0점으로 설정
aidt_utils.secure_send_score(0)
sys.exit(1)

선생님은 grader.py를 수정하여 다양한 방식으로 학생의 코드를 채점할 수 있습니다.

아래 예시를 통해 grader.py 작성 방법에 대해 알아봅시다.

[예시 1] 입출력 기반 채점

기본 세팅된 파일 구조에서 아래 폴더 & 파일을 추가합니다.

  • input 폴더 / output 폴더 : 채점을 위한 테스트 케이스를 정의합니다.

  • testcases.py 파일 : 각 테스트 케이스별 부분 점수 및 정 오답 메시지를 설정합니다.

▶️ 1) 입출력 채점을 위한 테스트 케이스 작성

채점을 위한 입출력 값을 저장하기 위한 파일을 생성한 후, 각 테스트 케이스를 작성합니다.

  • input 폴더

    • 테스트 케이스별 입력값을 txt 파일로 저장합니다.
    • 케이스별로 1개의 입력값을 저장합니다.
  • output 폴더

    • 테스트케이스 별 출력값을 txt 파일로 저장합니다.
    • input 폴더 내에 작성한 각 입력값에 대응하는 출력값을 저장합니다.

▶️ 2) 채점 메시지 작성

테스트 케이스에서 설정한 항목별 정 오답 메시지를 정의합니다.

또한, 각 테스트 케이스별 부분 점수를 설정합니다.

# testcase 별 정답 메시지
correct_messages = [
"testcase 1. 정답입니다!",
"testcase 2. 정답입니다!"
]

# testcase 별 오답 메시지
wrong_message = [
"testcase 1. 오답입니다!",
"testcase 2. 오답입니다!"
]

# testcase 별 부분 점수
scores = [50, 50]

▶️ 3) grader.py 채점코드 작성

테스트 케이스의 개수만큼 학생의 코드를 실행하여, 학생이 작성한 코드의 출력 결과를 확인합니다.

이후, 예측한 정답 출력값(output 파일)과 비교하여 실습의 정.오답을 판단합니다.

각 테스트 케이스 별로 부분 점수를 제공할 수 있으며, 최종 채점 결과는 aidt_utils.secure_send_score(total_score)를 통해 플랫폼(LXP) 내에 전송합니다.

예시 코드는 다음과 같습니다.

import os
import subprocess
import sys
from testcases import *
sys.path.append(os.getcwd())
from grader_aidt_utils import AIDTUtils # isort:skip

aidt_utils = AIDTUtils()
aidt_utils.secure_init()

SUM_TESTCASE_SCORES = 100
INPUT_DIR = '.aidt/input/'
OUTPUT_DIR = '.aidt/output/'

try:
total_score = 0

# 0. input, output 파일 불러오기
input_data = [
x for x in os.listdir(INPUT_DIR)
if x.endswith('.txt')
]
output_data = [
x for x in os.listdir(OUTPUT_DIR)
if x.endswith('.txt')
]

# 1. 테스트케이스 갯수 확인하기
if len(input_data) != len(output_data):
sys.exit(1)
NUM_TESTCASES = len(input_data)

# 2. 파일명 확인하기
matching = True
for i in range(1, NUM_TESTCASES + 1):
input_file = '%d.txt' % i
output_file = '%d.txt' % i

if input_file not in input_data:
matching = False
if output_file not in output_data:
matching = False
if not matching:
sys.exit(1)

# 3. 테스트케이스 별 채점 진행
for i in range(0, NUM_TESTCASES):
testcase_score = scores[i]
input_file = '%d.txt' % (i + 1)

input_text = subprocess.run(
['cat', '%s%s' % (INPUT_DIR, input_file)],
stdout=subprocess.PIPE
).stdout

result = subprocess.run(
['/bin/bash', '.aidt/runner.sh'],
input=input_text,
stdout=subprocess.PIPE
)

student_result = result.stdout.decode('utf-8').strip()
answer = ''.join(
open('%s%s' % (OUTPUT_DIR, input_file)).readlines()
).strip()

# 테스트케이스 별 정 오답 판단
if answer == student_result:
total_score += testcase_score # 테스트케이스 부분점수 추가
aidt_utils.secure_send_grader(
'✅ {} \n'.format(correct_messages[i])
)
else:
aidt_utils.secure_send_grader(
'❌ {} \n'.format(wrong_message[i])
)

# 5. 실습 최종 점수 계산
total_score = int(total_score)
aidt_utils.secure_send_score(total_score)

except Exception as err:
aidt_utils.secure_send_grader(
'채점 도중 오류가 발생했어요. 코드가 정상적으로 실행되는지 확인해 보세요.\n'
)
aidt_utils.secure_send_score(0)
sys.exit(1)

[예시 2] 특정 조건 확인

학생이 작성한 코드 파일을 불러온 후, 특정 조건이 성립하는지를 기준으로 채점을 진행할 수 있습니다.
아래 예시는 print() 함수를 3번 사용하여 3행시를 짓는 실습에 대한 정답 채점 코드입니다.

학생이 작성한 파일(main.py)을 불러온 후,
print() 함수가 총 3번 작성되었는지를 기준으로 실습을 채점합니다.

import os
import subprocess
import sys
from testcases import *
sys.path.append(os.getcwd())
from grader_aidt_utils import AIDTUtils # isort:skip

aidt_utils = AIDTUtils()
aidt_utils.secure_init()

try:
total_score = 0

# print() 함수를 3번 이상 사용했는지 확인하는 코드
count = 0
with open("main.py") as ans:
datafile = ans.readlines()
for line in datafile:
if 'print' in line:
count += 1

if count >= 3:
total_score += 100
aidt_utils.secure_send_grader(
'✅ 정답이에요! print()를 사용하여 멋진 삼행시를 지었군요! \n'
)
else:
aidt_utils.secure_send_grader(
'❌ 오답이에요! print()를 3번 사용해서 삼행시를 만들어 보세요.\n'
)

# 실습 최종 점수 전송
total_score = int(total_score)
aidt_utils.secure_send_score(total_score)

except Exception as err:
aidt_utils.secure_send_grader(
'채점 도중 오류가 발생했어요. 코드가 정상적으로 실행되는지 확인해보세요.\n'
)
aidt_utils.secure_send_score(0)
sys.exit(1)


grader.py를 작성하는 과정에서 유의할 점은 다음과 같습니다.

유의 사항 1

간혹 if문을 사용해 값을 비교할 때 형식과 형태가 맞지 않는 값을 비교할 경우 TypeError, RangeError 등의 오류가 발생할 수 있습니다. 이럴 경우, Grader는 즉시 동작을 멈추고 정상적인 채점이 이루어지지 않게 됩니다. 따라서 if문을 사용할 땐 다음의 코드와 같은 형식을 취하는 것을 권장합니다.

try:
if (
submission.drink_relfreq
== drink[drink['Attend'] == 1]['Name']
.value_counts(normalize=True)
).all():
total_score += 100
aidt_utils.secure_send_grader(
'상대도수를 올바르게 계산하셨습니다!\n'
)
except Exception:
aidt_utils.secure_send_grader(
'상대도수가 제대로 계산되지 않았어요. 다시 한번 계산해 볼까요?\n'
)

유의 사항 2

상황에 따라 세부적인 오류 내용을 구체적으로 명시해 주어야 하는 case가 발생할 수 있습니다.

이때는 내부 예외를 활용해 메시시지를 작성해 주세요.

Python 내부 예외에 대해서는 아래 링크를 참고해 주세요. https://docs.python.org/ko/3/library/exceptions.html#concrete-exceptions

import student_codes

try:
if student_codes.answer == 12:
total_score += 100
aidt_utils.secure_send_grader('정답!\n')

# index range error
except IndexError:
aidt_utils.secure_send_grader('인덱스가 지정된 범위를 벗어났어요.\n')

# name error
except NameError:
aidt_utils.secure_send_grader('선언하지 않은 변수를 사용했어요.\n')

# zero division error
except ZeroDivisionError:
aidt_utils.secure_send_grader('0으로는 나눌 수 없어요.\n')

유의 사항 3

채점 시 발생한 RuntimeError 메시지를 학생에게 제공한다면,
역으로 학생이 메시지 내용을 기반으로 테스트케이스를 유출할 수 있습니다.

따라서 다음과 같은 형태로 에러 메시시지를 작성하는 것을 권장합니다.

# 권장하지 않는 경우
try:
# 채점 코드 작성
except Exception as err:
aidt_utils.secure_send_grader(
'Internal Error:\n%s\n' % str(err)
)
aidt_utils.secure_send_score(0)
sys.exit(1)

# 권장하는 방법
try:
# 채점 코드 작성
except Exception:
aidt_utils.secure_send_grader(
'채점 도중 오류가 발생했어요. 코드가 정상적으로 실행되는지 확인해 보세요.\n'
)
aidt_utils.secure_send_score(0)
sys.exit(1)

"""
만약 권장하지 않는 경우로 채점 코드를 작성했을 경우?
"""
# grader.py 전문 출력 가능
raise Exception(
open('.aidt/grader.py').read()
)

7️⃣ 수업자료 지도서

선생님들께서 원하시는 바를 AI에 학습시켜 헬피에 즉각적으로 반영할 수 있습니다.

  1. 화면 상단의 수업자료 지도서를 클릭합니다.


  1. AI 모델 학습 참고 내용에 원하는 프롬프트를 입력할 수 있습니다.


  1. 우측 하단의 저장 버튼을 클릭하여 입력 내용을 저장합니다.


  1. 하단의 이미지처럼 선생님께서 입력하신 내용에 따라 헬피의 답변이 달라지는 것을 확인할 수 있습니다.
  • 수업자료 지도서 저장 전

  • 수업자료 지도서 저장 후