[멋쟁이 사자처럼 블록체인 스쿨 3기] 23-05-11

임형석·2023년 5월 11일
0

Solidity


Test

/*여러분은 선생님입니다. 학생들의 정보를 관리하려고 합니다. 
학생의 정보는 이름, 번호, 점수, 학점 그리고 듣는 수업들이 포함되어야 합니다.

번호는 1번부터 시작하여 정보를 기입하는 순으로 순차적으로 증가합니다.

학점은 점수에 따라 자동으로 계산되어 기입하게 합니다. 90점 이상 A, 80점 이상 B, 70점 이상 C, 60점 이상 D, 나머지는 F 입니다.

필요한 기능들은 아래와 같습니다.

* 학생 추가 기능 - 특정 학생의 정보를 추가
* 학생 조회 기능(1) - 특정 학생의 번호를 입력하면 그 학생 전체 정보를 반환
* 학생 조회 기능(2) - 특정 학생의 이름을 입력하면 그 학생 전체 정보를 반환
* 학생 점수 조회 기능 - 특정 학생의 이름을 입력하면 그 학생의 점수를 반환
* 학생 전체 숫자 조회 기능 - 현재 등록된 학생들의 숫자를 반환
* 학생 전체 정보 조회 기능 - 현재 등록된 모든 학생들의 정보를 반환
* 학생들의 전체 평균 점수 계산 기능 - 학생들의 전체 평균 점수를 반환
* 선생 지도 자격 자가 평가 시스템 - 학생들의 평균 점수가 70점 이상이면 true, 아니면 false를 반환
* 보충반 조회 기능 - F 학점을 받은 학생들의 숫자와 그 전체 정보를 반환
-------------------------------------------------------------------------------
* S반 조회 기능 - 가장 점수가 높은 학생 4명을 S반으로 설정하는데, 이 학생들의 전체 정보를 반환하는 기능 (S반은 4명으로 한정)

기입할 학생들의 정보는 아래와 같습니다.

Alice, 1, 85
Bob,2, 75
Charlie,3,60
Dwayne, 4, 90
Ellen,5,65
Fitz,6,50
Garret,7,80
Hubert,8,90
Isabel,9,100
Jane,10,70 */

위의 솔리디티 코딩 테스트 문제를 하나하나 풀어보자.


학생의 정보 설정

학생의 정보는 이름,번호,점수,학점,수업이다. 모두 다른 type 을 갖고 있으므로 struct 형태가 어울릴 것 같다.

    struct student {
        string name;
        uint number;
        uint score;
        string credit;
        string[] classes;
    }

학점 계산

학점은 점수에 따라 자동으로 계산되어 기입하게 합니다. 90점 이상 A, 80점 이상 B, 70점 이상 C, 60점 이상 D, 나머지는 F 입니다.

조건문을 포함한 함수를 만들어두고 나중에 다른 함수로 끌어와 사용하면 되겠다.

function setCredit(uint _score) public pure returns(string memory) {
        if(_score>=90){
            return "A";
        } else if(_score>=80){
            return "B";
        } else if(_score>=70){
            return "C";
        } else if(_score>=60){
            return "D";
        } else {
            return "F";
        }
    }

학생 추가

학생 추가 기능 - 특정 학생의 정보를 추가.

student 형식 students 를 상태변수로 선언하고, .push 를 이용해 배열에 넣어주면 되겠다.

여기서 number 는 students 배열 길이 + 1 값을 자동으로 넣게 만들었고

credit 은 앞서 만든 setCredit 함수를 불러와 사용하였다.

그러므로 이 함수의 input 값은 3가지이다.

function setStudent(string memory _name, uint _score, string[] memory _classes) public {
        students.push(student(_name, students.length+1, _score, setCredit(_score), _classes));
    }

학생 조회(1)

학생 조회 기능(1) - 특정 학생의 번호를 입력하면 그 학생 전체 정보를 반환

uint 형 input 을 받고, 이걸 배열에 넘겨주어 값을 반환받으면 되겠다.

-1 을 적어주어 배열이 1부터 시작하는걸로 쉽게 인식할 수 있도록 했다.

function getStudent(uint _number) public view returns(student memory) {
        return students[_number-1];
    }

학생 조회(2)

학생 조회 기능(2) - 특정 학생의 이름을 입력하면 그 학생 전체 정보를 반환

학생의 이름을 받아서 곧바로 배열에 넘겨주어 해당 학생을 반환 받는건 불가능하다.

그렇기에, mapping 을 사용하여 string 형 키를 받아서 student 값을 받아오도록 setStudent 함수의 코드를 다시 짠다.

mapping(string=>student) newstudents;

function setStudent(string memory _name, uint _score, string[] memory _classes) public {
        students.push(student(_name, students.length+1, _score, setCredit(_score), _classes));
        mapstudents[_name] = student(_name, students.length, _score, setCredit(_score), _classes);
    }

function getStudent2(string memory _name) public view returns(student memory) {
        return mapstudents[_name];
    }

학생 점수 조회

학생 점수 조회 기능 - 특정 학생의 이름을 입력하면 그 학생의 점수를 반환

위와 비슷한 함수이다. 점수만을 반환하므로 returns 는 uint, return 의 맨뒤에는 .score 만 붙여주면 되겠다.

function getStudent3(string memory _name) public view returns(uint) {
        return mapstudents[_name].score;
    }

학생 전체 숫자 조회

학생 전체 숫자 조회 기능 - 현재 등록된 학생들의 숫자를 반환

현재 등록된 학생의 숫자는 students 배열의 길이로 가져오면 되겠다.

function getStudent4() public view returns(uint) {
        return students.length;
    }

학생 전체 정보 조회

학생 전체 정보 조회 기능 - 현재 등록된 모든 학생들의 정보를 반환

현재 등록된 모든 학생들은 students 배열을 그대로 가져오면 되겠다.

function getStudent5() public view returns(student[] memory) {
        return students;
    }

전체 평균 점수 계산

학생들의 전체 평균 점수 계산 기능 - 학생들의 전체 평균 점수를 반환

평균 점수 = 모든 점수 / 학생 수

students 배열의 모든 score 를 더해서 length 로 나누어주면 되겠다.

여기서 배열의 모든 숫자를 가져오려면 어떻게 해야할까?

반복문인 for 를 사용하여 모든 students 배열의 score 를 가져오고,

임의의 지역변수에 저장한다.

그리고 for 문의 반복이 끝나면, 지역변수 값을 불러와서 length(학생수) 로 나누어주고 반환하면 되겠다.

function getAverage() public view returns(uint) {
        uint sum;
        for(uint i; i<students.length; i++){
            sum = sum + students[i].score;
        }
        return sum / students.length;
        // return sum / getstudent4(); 로 작성해도 됨.
    }

선생 평가 시스템

선생 지도 자격 자가 평가 시스템 - 학생들의 평균 점수가 70점 이상이면 true, 아니면 false를 반환

평균 점수를 가져오는 것은 위에 작성한 getAverage 함수를 가져와 사용하고,

true, false 를 반환한다면 boolean 형을 사용하면 되겠다.

function evaluateSys() public view returns(bool) {
        if(getAverage() >= 70){
            return true;
        } else {
            return false;
        }
    }

보충반 조회

보충반 조회 기능 - F 학점을 받은 학생들의 숫자와 그 전체 정보를 반환

students 배열에서 credit 이 F 인 학생을 골라야 하므로 for 문안에 if 문을 사용하여 F 인 학생을 상태변수에 저장.

if 문안에서 students[i].credit == "F" 을 사용하면 에러가 뜬다.

이 에러는, string 끼리의 비교에는 == 을 사용할 수 없다는 내용이다.

솔리디티에서는 위 에러처럼 string 과 string 의 비교는 불가능하다.

그래서 bytes 형태로 감싸주고, 이것을 keccak256 으로 해싱해주어 그 값을 비교한다.

student[] fstudents;

    function getF() public returns(uint) {
        for(uint i; i < students.length; i++){
            if(keccak256(bytes(students[i].credit)) == keccak256(bytes("F"))){
                fstudents.push(students[i]);
            }
        }
        return fstudents.length;
    } 

S 반 조회

S반 조회 기능 - 가장 점수가 높은 학생 4명을 S반으로 설정하는데, 이 학생들의 전체 정보를 반환하는 기능 (S반은 4명으로 한정)

나중에...

0개의 댓글