// SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.0; /* 학생관리 프로그램 확장판입니다. 아래에 11월 17, 21, 25일의 학생부 관리 프로그램의 문제가 있습니다. ------------------------------ 11/17/2022 1번 지갑은 선생님입니다. 2,3,4,5,6,7,8,9,10번은 학생입니다. 이름, 번호, 생일, 점수 그리고 학점을 포함한 학생이라는 구조체를 생성하고 학생을 추가하고 삭제하고 조회하는 기능을 추가하세요. 학점은 90점 이상이면 A, 90점 미만 80점 이상이면 B, 80점 미만 70점 이상이면 C, 70점 미만 60점 이상이면 D 그 이외는 F 입니다. 학생 추가 기능 - 이 기능은 누구나 사용할 수 있습니다만 = 보통 학생들이 직접 사용할 예정입니다. 학생들이 본인의 정보를 추가할 때 자신의 지갑주소와 mapping이 될 수 있게 해주세요. (값은 임의대로 넣으세요) 학생 삭제 기능 - 이 기능은 특정 주소의 지갑소유자(선생님)만이 실행할 수 있습니다. 삭제할 때는 학생의 지갑주소를 기반으로 삭제합니다. 학생 조회 기능 - 이 기능은 누구나 사용할 수 있습니다. 조회할 때는 학생의 지갑 주소를 기반으로 조회합니다. 조회는 이름, 번호, 생일, 점수 그리고 학점을 모두 조회할 수 있어야 합니다. 심화반 신청 - 학생들이 사용하는 기능입니다. 학점이 B 이상인 학생들만 수강할 수 있는 반입니다. 선생님 신청 - 지갑의 주소가 선생임을 증명할 수 있게 선생님 신청을 할 수 있는 기능을 만들어주세요. ------------------------------ 11/21/2022 이름 번호 점수를 가진 학생 구조체를 생성하시오. 학생의 등록과 삭제는 선생님만 가능합니다. 학생들의 점수 총합을 구하고 이를 확인할 수 있는 기능을 구현하시오. 학생의 삭제는 전학이라고 생각하시면 됩니다. 학생 구성의 변화가 있으면 총합의 양도 갱신해주세요. 번호는 알파벳 순으로 입력하고 전학, 전입시에는 자동으로 갱신해주세요. 학생 구성 A-84 B-75 C-80 D-85 E-90 D 전학 F 전입 F-95 C전학 번호 예시 평소 -> A - 1번 , B - 2번 , C - 3번 B 전학 -> A - 1번 , C - 2번 E 전입 -> A - 1번 , C - 2번, E - 3번 ------------------------------ 11/25/2022 학생 점수관리 프로그램입니다. 여러분은 한 학급을 맡았습니다. 학생은 번호, 이름, 점수로 구성되어 있고(구조체) 가장 점수가 낮은 사람을 집중관리하려고 합니다. 가장 점수가 낮은 사람의 정보를 보여주는 기능, 총 점수 합계, 총 점수 평균을 보여주는 기능, 특정 학생을 반환하는 기능, 가능하다면 학생 전체를 반환하는 기능을 구현하세요. ([] <- array) ------------------------------ 11/30/2022 하나의 컨트랙트로 통합하여 주세요. 추가로 자신의 관할 교육청을 등록하는 함수도 만들어주세요. (주소로 관리되면 됩니다.) 이번에는 교육청 입장입니다. 여기에 추가하여 각 학교들의 평균점수와 그 평균점수를 기반으로 하여 학교를 평가하는 컨트랙트를 만드세요. 이 컨트랙트는 교육청이 관리합니다. 학생들의 평균 점수가 80이상이면 A등급, 60이상이면 B등급 그리고 나머지는 C등급을 부여하세요. 교육청은 각 학교의 등급, 최저점 학생의 정보와 심화반 학생 수를 알아야 합니다. 또한, 학생이 새로운 학교로 등록하고 싶을 때 이 교육청 컨트랙트를 통해 등록해야 합니다.(타컨트랙트 함수 이용) 스스로 등록할 수 있습니다. 학생 등록함수는 한가지 더 있는데, 이는 교육청만 할 수 있습니다. 학생이 원하는 학교에 등록하는 것이 아니라 임의로 교육청이 학생을 특정학교 등록하는 것입니다. 만약 학생의 점수가 80점 이상이면 C학교에 60점 이상이면 A학교에 그 외에는 B학교에 등록되게 설정해주세요. */ contract DistrictContr { /* ---------------------------------------------------------------- */ /* --------------------------- CONTRACT --------------------------- */ /* ---------------------------------------------------------------- */ SchoolContr public schoolContrVar; // constructor(address _contrAddr) { // schoolContrVar = SchoolContr(_contrAddr); // } function inheritSchoolContr(address _contrAddr) public { // constructor()로 만들지 않고 getContract(address _contractAddr)로 만들면 여러 학교 컨트랙 (함수 + 변수) 가져올 수 있나요? 그리고 그러면 동일이름 함수 및 변수들 충돌하지 않나요? schoolContrVar = SchoolContr(_contrAddr); } /* ---------------------------------------------------------------- */ /* --------------------------- SCHOOLS ---------------------------- */ /* ---------------------------------------------------------------- */ /* Schools DB */ mapping(address => School) schoolsMap; // 변수명, type이 많아서 관리가 잘 안되는데 변수명에 type 같이 표현하는 것 best practice? struct School { // struct name School = contract name School이면 Warning: This declaration shadows an existing declaration address addr; string grade; uint avgScore; uint numOfAdvClassStudents; uint numOfLowestScoredStudents; } /* Read scores */ function getAvgScore() public view returns(uint) { return schoolContrVar.getAvgScore(); } function getGrade() public returns(string memory) { uint avgScore = getAvgScore(); return setGrade(avgScore); } /* Update scores */ function setGrade(uint _score) private returns(string memory) { string memory grade; if (_score >= 80) { grade = 'A'; } else if (_score >= 60) { grade = 'B'; } else { grade = 'C'; } return grade; } /* Read adv class students */ function getAdvClassStudentsArrLen() public view returns(uint) { return schoolContrVar.getAdvClassStudentsArrLen(); } /* Read lowest scored students */ // function getLowestArr() public view returns(Student[] memory) { // School contract (line 223)에서 만든 Student[] LowestArr를 상속하는 방법이 있을까요? Student[] public로 지정해도 다음 에러가 납니다. DeclarationError: Identifier not found or not unique // return schoolContrVar.getLowestArr(); // } function getLowestArrLen() public view returns(uint) { return schoolContrVar.getLowestArrLen(); } } contract SchoolContr { /* ---------------------------------------------------------------- */ /* --------------------------- CONTRACT --------------------------- */ /* ---------------------------------------------------------------- */ DistrictContr public districtContrVar; address districtAddr; function setDistrictAddr(address _addr) public returns(string memory) { districtAddr = _addr; return "Registered"; } // SchoolContr와 (SchoolContract로부터 함수, 변수를 가져온) DistrictContr가 양방향으로 함수, 변수를 가져올 수 있으면 충동이 나는 경우도 있나요? /* ---------------------------------------------------------------- */ /* --------------------------- Teachers --------------------------- */ /* ---------------------------------------------------------------- */ /* Teacher DB */ address teacherAddr; /* Create teachers */ function setTeacherAddr() public returns(string memory) { teacherAddr = address(msg.sender); return "Registered"; } /* Read teachers */ function getTeacherAddr() public view returns(address) { return teacherAddr; } /* ---------------------------------------------------------------- */ /* --------------------------- Students --------------------------- */ /* ---------------------------------------------------------------- */ /* Students DB */ mapping(address => Student) studentsMap; // Dual DB - mapping Student[] studentsArr; // Dual DB - array struct Student { uint num; string name; uint bod; uint score; string grade; } function getArrLen() public view returns(uint) { return studentsArr.length; } /* Create students */ function setStudent(string memory _name, uint _bod, uint _score) public { // require(msg.sender == teacherAddr, "Not qualified"); // Conflicting instructions uint _num = studentsArr.length + 1; string memory _grade = setGrade(_score); /* mapping registeration */ studentsMap[msg.sender] = Student(_num, _name, _bod, _score, _grade); /* array registration */ studentsArr.push(Student(_num, _name, _bod, _score, _grade)); } /* Read students */ function getStudent(address _addr) public view returns(Student memory) { return studentsMap[_addr]; } function getAllStudents() public view returns(Student[] memory) { return studentsArr; } /* Delete students */ function delStudent(uint _num) public { require(msg.sender == teacherAddr, "Not qualified"); /* mapping deletion */ delete studentsMap[msg.sender]; // mapping에서 지우는 방법 맞나요? /* array deletion */ for (_num; _num < studentsArr.length; _num += 1) { studentsArr[_num].num -= 1; // Missed // studentsArr[_num - 1].num = studentsArr[_num].num; studentsArr[_num - 1] = studentsArr[_num]; } studentsArr.pop(); } /* ---------------------------------------------------------------- */ /* ------------------- ADVANCED CLASS STUDETNS -------------------- */ /* ---------------------------------------------------------------- */ /* Create advanced class students */ address[] advClassStudentsArr; function setAdvClassStudent() public returns(string memory) { // require(studentsMap[address(msg.sender)].score >= 80, "Not qualified"); string memory _grade = studentsMap[address(msg.sender)].grade; require(keccak256(bytes(_grade)) == keccak256('A') || keccak256(bytes(_grade)) == 'B', "Not qualified"); advClassStudentsArr.push(address(msg.sender)); return "Registered"; } function getAdvClassStudentsArrLen() public view returns(uint) { return advClassStudentsArr.length; } /* ---------------------------------------------------------------- */ /* -------------------- LOWEST SCORED STUDETNS -------------------- */ /* ---------------------------------------------------------------- */ /* Lowest scored students DB */ Student[] LowestArr; /* Read lowest scored students */ function getLowestScoredStudent() public returns(Student[] memory) { /* Clean up array */ delLowestArr(); /* Anchor index initialized */ uint _lowestNum; /* Run comparison iterations to find lowest score's i */ for(uint i = _lowestNum + 1; i < studentsArr.length; i++) { if(studentsArr[i].score < studentsArr[_lowestNum].score) { _lowestNum = i; } } /* Run iterations to find i's matching the lowest score */ for(uint i; i < studentsArr.length; i++) { if(studentsArr[i].score == studentsArr[_lowestNum].score) { LowestArr.push(studentsArr[i]); } } return LowestArr; } function getLowestArr() public view returns(Student[] memory) { // No automatic updating; Call this function only after updating array return LowestArr; } function getLowestArrLen() public view returns(uint) { return LowestArr.length; } /* Delete Lowest scored students */ function delLowestArr() private { uint lowestArrLen = LowestArr.length; for(uint i; i < lowestArrLen; i++) { LowestArr.pop(); } } /* ---------------------------------------------------------------- */ /* ---------------------------- SCORES ---------------------------- */ /* ---------------------------------------------------------------- */ /* Read scores */ function getSumScore() public view returns(uint) { uint sumScore; for(uint i; i < studentsArr.length; i++) { if(studentsArr[i].score >= 0) { sumScore += studentsArr[i].score; } } return sumScore; } function getAvgScore() public view returns(uint) { return getSumScore() / studentsArr.length; } /* Update scores */ function setGrade(uint _score) private returns(string memory) { string memory grade; if (_score >= 90) { grade = 'A'; } else if (_score >= 80) { grade = 'B'; } else if (_score >= 70) { grade = 'C'; } else if (_score >= 60) { grade = 'D'; } else { grade = 'F'; } return grade; } }
0.7.1