03.TypeScript

01.*Create a class hierarchy by your choice with TypeScript consisting of the following:
– At least 2 modules
– At least 3 interfaces
– At least 6 classes
– At least 2 uses of inheritance
– At least 12 methods
– At least one generic use
– At least one static use
– Everything should be strongly typed

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>01.ClassHierarchy</title>
    <link rel="stylesheet" href="app.css" type="text/css" />  
</head>
<body>
    <h1>You can see test results in console.</h1>

    <script src="Education/Discipline.js"></script>
    <script src="Persons/Person.js"></script>
    <script src="Persons/Student.js"></script>
    <script src="Persons/Teacher.js"></script>
    <script src="Education/MajorType.js"></script>
    <script src="Education/Major.js"></script>
    <script src="Education/University.js"></script>
    <script src="Education/Exam.js"></script>
    <script src="app.js"></script>
</body>
</html>

app.css

body {
    font-family: 'Segoe UI', sans-serif;
}

span {
    font-style: italic;
}

app.ts

console.group('-----------------------------------------------------------------------------------------------------');
var teodorStudent: Persons.Student = new Persons.Student('Teodor Teodorov', '9101012233', 1, '199222');
teodorStudent.addMarks(Education.Discipline.Database, [6, 5, 4, 6, 3]);
teodorStudent.addMarks(Education.Discipline.JavaProgramming, [4, 4, 2, 6, 6]);

var ivanStudent: Persons.Student = new Persons.Student('Ivan Ivanov', '9110102233', 4, '101111');
ivanStudent.addMarks(Education.Discipline.WebDesign, [5, 5, 6, 5, 5]);

var mariaTeacher: Persons.Teacher = new Persons.Teacher('Maria Getova', '6404023233', '20 years',
    [Education.Discipline.Database, Education.Discipline.Criptography, Education.Discipline.Math]);

var kirilTeacher: Persons.Teacher = new Persons.Teacher('Kiril Petev', '8812129900', '11 months', [Education.Discipline.JavaProgramming]);

var computerScienceStudents: Persons.Student[] = [
    teodorStudent,
    ivanStudent,
    new Persons.Student('Maria Dimitrova', '9101022211', 4, '101213'),
    new Persons.Student('Hristo Petkov', '9408070111', 1, '131322'),
    new Persons.Student('Georgi Georgiev', '8920113212', 2, '132001'),
    new Persons.Student('Kristina Ivanova', '8801012101', 3, '432122')
];

var computerScienceMajor: Education.Major = new Education.Major(Education.MajorType.ComputerScience, computerScienceStudents);
computerScienceMajor.addStudent(new Persons.Student('Valentin Koev', '9312241022', 2, '099122'));
computerScienceMajor.removeStudent(ivanStudent);
computerScienceMajor.printMajor(); 
console.log('Is student ' + ivanStudent.fullName + ' still exist in computer science major: ' + computerScienceMajor.containsStudent(ivanStudent));

console.log('-----------------------------------------------------------------------------------------------------');
console.groupEnd();

console.group('-----------------------------------------------------------------------------------------------------');
var university: Education.University = new Education.University('Software University', [mariaTeacher, kirilTeacher]);
university.addTeacher(new Persons.Teacher('Denis Koev', '8012091233', 'no experience'));
university.addMajor(new Education.Major(Education.MajorType.Chemistry, [new Persons.Student('Mitko Ivanov', '9202061222', 1, '151102'), ivanStudent]));
university.printUniversity();

console.log('-----------------------------------------------------------------------------------------------------');
console.groupEnd();

console.group('-----------------------------------------------------------------------------------------------------');
var exam: Education.Exam<Persons.Teacher, Persons.Student> = new Education.Exam<Persons.Teacher, Persons.Student>
    (Education.MajorType.Electronics, Education.Discipline.Math, new Persons.Teacher('Daniel Petrov', '5009162314', '30 years',
        [Education.Discipline.Math, Education.Discipline.OOP]), [new Persons.Student('Kamelia Koleva', '9104121444', 4, '110033')]);

exam.printExam();
console.log('-----------------------------------------------------------------------------------------------------');
console.groupEnd();

Persons/Person.ts

module Persons {
    'use strict';

    export class Person {
        private static MIN_AGE: number = 0;
        private static MAX_AGE: number = 100;
        private static MAX_DIGITS_IN_ID = 10;
        private _fullName: string;
        private _id: string;
        private static _idNumbers: string[] = [];
        
        constructor(fullName: string, id: string) {
            this.fullName = fullName;
            this.id = id;
        }

        public get fullName(): string {
            return this._fullName;
        }

        public set fullName(fullName: string) {
            if (fullName === null || fullName === '') {
                throw new Error('Full name cannot be null or empty!');
            }
             
            this._fullName = fullName;
        }

        public get id(): string {
            return this._id;
        }

        public set id(idNumber: string) {
            if (idNumber === null || idNumber === '') {
                throw new Error('ID number cannot be null or empty!');
            }
            else if (!this.isIdValid(idNumber)) {
                throw new Error('ID number must contains ' + Person.MAX_DIGITS_IN_ID + ' digits!');
            }
            else if (Person.isIdAlreadyExist(idNumber)) {
                throw new Error('ID number already exist!');
            }

            this._id = idNumber;
            Person._idNumbers.push(idNumber);
        }

        public printPerson(): void {
            console.log('Full name: ' + this.fullName + ', ID: ' + this.id);
        }

        private isIdValid(id: string): boolean {
            if (id.length !== 10) {
                return false;
            }
            else if (!(/^\d+$/.test(id))) {
                return false;
            }
            
            return true;
        }

        private static isIdAlreadyExist(id: string): boolean {
            return Person._idNumbers.indexOf(id) !== -1;
        }
    }
}

Persons/Student.ts

module Persons {
    'use strict';

    export class Student extends Persons.Person implements Interfaces.IStudent {
        private static MIN_COURSE = 1;
        private static MAX_COURSE = 5;
        private static MIN_MARK = 2;
        private static MAX_MARK = 6;
        private _course: number;
        private _facultyNumber: string;
        private _marks: number[];
        private static _facultyNumbers: string[] = [];

        constructor(fullname: string, id: string, course: number, facultyNumber: string) {
            super(fullname, id);
            this.course = course;
            this.facultyNumber = facultyNumber;
            this._marks = [];
        }

        public get course(): number {
            return this._course;
        }

        public set course(course) {
            if (course < Student.MIN_COURSE || course > Student.MAX_COURSE) {
                throw new Error('Course must be in the interval [' + Student.MIN_COURSE + ' - ' + Student.MAX_COURSE + ']!');
            }
            
            this._course = course;
        }

        public get facultyNumber(): string {
            return this._facultyNumber;
        }

        public set facultyNumber(facultyNumber: string) {
            if (facultyNumber === null || facultyNumber === '') {
                throw new Error('Faculty number cannot be null or empty!');
            }
            else if (Student.isFacultyNumberAlreadyExist(facultyNumber)) {
                throw new Error('Faculty number already exist!');
            }

            this._facultyNumber = facultyNumber;
            Student._facultyNumbers.push(facultyNumber);
        }

        public get marks(): number[] {
            return this._marks;
        }

        public addMark(discipline: string, mark: number): void {
            var disciplineMarks: number[] = [];
            this.isDisciplineValid(discipline)
          
            if (!this.isMarkValid(mark)) {
                throw new Error('Mark must be an integer number in interval [' + Student.MIN_MARK + ' - ' + Student.MAX_MARK + ']!');
            }

            if (!this._marks[discipline]) {
                this._marks[discipline] = [mark];
            }
            else {
                disciplineMarks = this._marks[discipline];
                disciplineMarks.push(mark);
                this._marks[discipline] = disciplineMarks;
            }
        }

        public addMarks(discipline: string, marks: number[]): void {
            this.isDisciplineValid(discipline);

            marks.forEach(mark => {
                if (!this.isMarkValid(mark)) {
                    throw new Error('Mark must be an integer number in interval [' + Student.MIN_MARK + ' - ' + Student.MAX_MARK + ']!');
                }
            });

            this._marks[discipline] = marks;
        }

        public getAverageMark(discipline: string): number {
            var disciplineMarks: number[] = this._marks[discipline],
                averageMark = 0;

            this.isDisciplineValid(discipline);
            disciplineMarks.forEach(mark => {
                averageMark += mark;
            });

            return averageMark / disciplineMarks.length;
        }

        public clearMarks(): void {
            this._marks = [];
        }

        public printStudent(): void {
            var discipline;

            super.printPerson();
            console.log('Course: ' + this.course + ', Faculty number: ' + this.facultyNumber);
            console.group('Marks: ');

            for (discipline in this._marks) {
                console.log(discipline + ': ' + '[' + this._marks[discipline] + '] -> ' + this.getAverageMark(discipline));
            }

            if (!discipline) {
                console.log('There are no marks!');
            }

            console.groupEnd();
            console.log('\n');
        }

        private static isFacultyNumberAlreadyExist(facultyNumber: string): boolean {
            return Student._facultyNumbers.indexOf(facultyNumber) !== -1;
        }

        private isDisciplineValid(discipline: string): boolean {
            if (discipline === null || discipline === '') {
                throw new Error('Discipline cannot be null or empty!');
            }
            else if (!Education.Discipline.isDisciplineValid(discipline)) {
                throw new Error('There is no such discipline!');
            }

            return true;
        }

        private isMarkValid(mark: number): boolean {
            return (mark >= Student.MIN_MARK && mark <= Student.MAX_MARK) &&
                (parseInt(mark.toString()) === parseFloat(mark.toString()));
        }
    }
} 

Persons/Teacher.ts

module Persons {
    'use strict';

    export class Teacher extends Persons.Person implements Interfaces.ITeacher {
        private _experience: string;
        private _disciplines: string[];

        constructor(fullname: string, id: string, experience: string, disciplines?: string[]) {
            var isAllDisciplinesValid: boolean = true; 
            super(fullname, id);
            this.experience = experience;

            if (disciplines) {
                disciplines.forEach(currentDiscipline => {
                    if (!Education.Discipline.isDisciplineValid(currentDiscipline)) {
                        throw new Error('There is no such discipline!');
                    }
                });

                this._disciplines = disciplines;
            }
            else {
                this._disciplines = [];
            }
        }

        public get experience(): string {
            return this._experience;
        }

        public set experience(experience: string) {
            if (experience === null || experience === '') {
                throw new Error('Experience cannot be null or empty!');
            }
            
            this._experience = experience;
        }

        public get disciplines(): string[] {
            return this._disciplines;
        }

        public addDiscipline(discipline: string): void {
            if (!Education.Discipline.isDisciplineValid(discipline)) {
                throw new Error('There is no such discipline!');
            }
            else if (this.containsDiscipline(discipline)) {
                throw new Error('Discipline already exist!');
            }

            this._disciplines.push(discipline);
        }

        public containsDiscipline(discipline: string): boolean {
            return this._disciplines.indexOf(discipline) !== -1;
        }

        public removeDiscipline(discipline: string): boolean {
            if (this.containsDiscipline(discipline)) {
                var disciplineIndex = this._disciplines.indexOf(discipline);
                this._disciplines[disciplineIndex] = this._disciplines[this._disciplines.length - 1];
                this._disciplines.pop();
                return true;
            }

            return false;
        }

        public printTeacher(): void {
            super.printPerson();
            console.log('Experience: ' + this.experience);
            console.group('Disciplines: ');

            if (this._disciplines.length > 0) {    
                this._disciplines.forEach(discipline => {
                    console.log(discipline);
                });
            }
            else {
                console.log('There are no disciplines!');
            }

            console.groupEnd();
            console.log('\n');
        }
    }
} 

Interfaces/IStudent.ts

module Interfaces {
    'use strict';

    export interface IStudent {
        addMark(discipline: string, mark: number): void;
        addMarks(discipline: string, arrayOfMarks: number[]): void;
        getAverageMark(discipline: string): number;
        clearMarks(): void;
        printStudent(): void;
    }
} 

Interfaces/ITeacher.ts

module Interfaces {
    'use strict';

    export interface ITeacher {
        addDiscipline(discipline: Education.Discipline): void;
        containsDiscipline(discipline: Education.Discipline): boolean;
        removeDiscipline(discipline: Education.Discipline): boolean;
        printTeacher(): void;
    }
}

Interfaces/IMajor.ts

module Interfaces {
    'use strict';

    export interface IMajor {
        addStudent(student: Persons.Student): void; 
        containsStudent(student: Persons.Student): boolean;
        removeStudent(student: Persons.Student): void;
        clearStudents(): void;
        printMajor(): void;
    }
} 

Interfaces/IUniversity.ts

module Interfaces {
    'use strict';

    export interface IUniversity {
        addTeacher(teacher: Persons.Teacher): void;
        containsTeacher(teacher: Persons.Teacher): boolean;
        removeTeacher(teacher: Persons.Teacher): boolean;
        addMajor(major: Education.Major): void;
        containsMajor(major: Education.Major): boolean;
        removeMajor(major: Education.Major): boolean;
        getNumberOfStudents(): number;
        printUniversity(): void;
    } 
}

Education/Discipline.ts

module Education {
    'use strict';

    export class Discipline {
        private static _oop: string = 'OOP';
        private static _criptography: string = 'Cryptography';
        private static _math: string = 'Math';
        private static _javaProgramming: string = 'JAVA Programming';
        private static _english: string = 'English';
        private static _database: string = 'Database';
        private static _artificialIntelligence: string = 'Artificial Intelligence';
        private static _webDesign: string = 'Web Design';
        private static _disciplines: string[] = [Discipline._oop, Discipline._criptography, Discipline._math, Discipline._javaProgramming,
        Discipline._english, Discipline._database, Discipline._artificialIntelligence, Discipline._webDesign];

        public static get OOP(): string {
            return Discipline._oop;
        }

        public static get Criptography(): string {
            return Discipline._criptography;
        }

        public static get Math(): string {
            return Discipline._math;
        }

        public static get JavaProgramming(): string {
            return Discipline._javaProgramming;
        }

        public static get English(): string {
            return Discipline._english;
        }

        public static get Database(): string {
            return Discipline._database;
        }

        public static get ArtificialIntelligence(): string {
            return Discipline._artificialIntelligence;
        }

        public static get WebDesign(): string {
            return Discipline._webDesign;
        }

        public static get Disciplines(): string[] {
            return Discipline._disciplines;
        }

        public static isDisciplineValid(discipline: string): boolean {
            if (discipline === null || discipline === '') {
                throw new Error('Discipline cannot be null or empty!');
            }

            for (var i = 0; i < Discipline._disciplines.length; i += 1) {
                if (Discipline._disciplines[i] === discipline) {
                    return true;
                }
            }
            
            return false;
        }
    }
} 

Education/MajorType.ts

module Education {
    'use strict';

    export class MajorType {
        private static _electronics: string = 'Electronics';
        private static _mechanicalEngineering: string = 'Mechanical Engineering';
        private static _computerScience: string = 'Computer Science';
        private static _businessManagement: string = 'Business Management';
        private static _geography: string = 'Geography';
        private static _math: string = 'Math';
        private static _marketing: string = 'Marketing';
        private static _chemistry: string = 'Chemistry';
        private static _economy: string = 'Economy';
        private static _law: string = 'Law';
        private static _computerTechnology: string = 'Computer Technology';
        private static _majorTypes: string[] = [MajorType._electronics, MajorType._mechanicalEngineering, MajorType._computerScience,
            MajorType._businessManagement, MajorType._geography, MajorType._math, MajorType._marketing, MajorType._chemistry,
            MajorType._economy, MajorType._law, MajorType._computerTechnology];

        public static get Electronics(): string {
            return MajorType._electronics;
        }

        public static get MechanicalEngineering(): string {
            return MajorType._mechanicalEngineering;
        }

        public static get ComputerScience(): string {
            return MajorType._computerScience;
        }

        public static get BusinessManagement(): string {
            return MajorType._businessManagement;
        }

        public static get Geography(): string {
            return MajorType._geography;
        }

        public static get Math(): string {
            return MajorType._math;
        }

        public static get Marketing(): string {
            return MajorType._marketing;
        }
        
        public static get Chemistry(): string {
            return MajorType._chemistry;
        }

        public static get Economy(): string {
            return MajorType._economy;
        }

        public static get Law(): string {
            return MajorType._law;
        }

        public static get ComputerTechnology(): string {
            return MajorType._computerTechnology;
        }

        public static get MajorTypes(): string[] {
            return this._majorTypes;
        }

        public static isMajorTypeValid(majorType: string): boolean {
            if (majorType === null || majorType === '') {
                throw new Error('Major type cannot be null or empty!');
            }

            for (var i = 0; i < MajorType._majorTypes.length; i += 1) {
                if (MajorType._majorTypes[i] === majorType) {
                    return true;
                }
            }

            return false;
        }
    }
}

Education/Major.ts

module Education {
    'use strict';

    export class Major implements Interfaces.IMajor {
        private _majorType: string;
        private _students: Persons.Student[];

        constructor(majorType: string, students?: Persons.Student[]) {
            this.majorType = majorType;
            
            if (students) {
                this._students = students;
            }
            else {
                this._students = [];
            }
        }

        public get majorType(): string {
            return this._majorType;
        }

        public set majorType(majorType: string) {
            if (!Education.MajorType.isMajorTypeValid(majorType)) {
                throw new Error('There is no sych major type!');
            }

            this._majorType = majorType;
        }

        public get students(): Persons.Student[] {
            return this._students;
        }

        public addStudent(student: Persons.Student): void {
            this._students.push(student);
        }

        public containsStudent(student: Persons.Student): boolean {
            return this._students.indexOf(student) !== -1;
        }

        public removeStudent(student: Persons.Student): boolean {
            if (this.containsStudent(student)) {
                var studentIndex: number = this._students.indexOf(student);
                this._students[studentIndex] = this._students[this._students.length - 1];
                this._students.pop();
                return true
            }
            
            return false;
        }

        public clearStudents(): void {
            this._students = [];
        }

        public printMajor(): void {
            console.group('Major: ' + this.majorType);
            console.group('Students: ');

            if (this._students.length > 0) {    
                this._students.forEach(student => {
                    student.printStudent();
                });

                console.groupEnd();
            }
            else {
                console.log('There are no students in this major!');
            }

            console.groupEnd();
        }
    }
} 

Education/University.ts

module Education {
    'use strict';

    export class University implements Interfaces.IUniversity {
        private _universityName: string;
        private _teachers: Persons.Teacher[];
        private _majors: Education.Major[];

        constructor(universityName: string, teachers?: Persons.Teacher[], majors?: Education.Major[]) {
            this.universityName = universityName;

            if (teachers) {
                this._teachers = teachers;
            }
            else {
                this._teachers = [];
            }

            if (majors) {
                this._majors = majors;
            }
            else {
                this._majors = [];
            }
        }

        public get universityName(): string {
            return this._universityName;
        }

        public set universityName(universityName: string) {
            if (universityName === null || universityName === '') {
                throw new Error('University name cannot be null or empty!');
            }
             
            this._universityName = universityName;
        }

        public get teachers(): Persons.Teacher[] {
            return this._teachers;
        }

        public get majors(): Education.Major[] {
            return this._majors;
        }

        public addTeacher(teacher: Persons.Teacher): void {
            this._teachers.push(teacher);
        }

        public containsTeacher(teacher: Persons.Teacher): boolean {
            return this._teachers.indexOf(teacher) !== - 1;
        }

        public removeTeacher(teacher: Persons.Teacher): boolean {
            if (this.containsTeacher(teacher)) {
                var teacherIndex: number = this._teachers.indexOf(teacher);
                this._teachers[teacherIndex] = this._teachers[this._teachers.length - 1];
                this._teachers.pop();
                return true;
            }

            return false;
        }

        public addMajor(major: Education.Major): void {
            if (this.containsMajor(major)) {
                throw new Error('Major already exist!');
            }

            this._majors.push(major);
        }

        public containsMajor(major: Education.Major): boolean {
            return this._majors.indexOf(major) !== - 1;
        }

        public removeMajor(major: Education.Major): boolean {
            if (this.containsMajor(major)) {
                var majorIndex: number = this._majors.indexOf(major);
                this._majors[majorIndex] = this._majors[this._majors.length - 1];
                this._majors.pop();
                return true;
            }

            return false;
        }

        public getNumberOfStudents(): number {
            var numberOfStudents: number = 0;

            this._majors.forEach(major => {
                numberOfStudents += major.students.length;
            });

            return numberOfStudents;
        }

        public printUniversity(): void {
            console.group('University name: ' + this.universityName);
            console.log('Number of teachers: ' + this._teachers.length);
            console.log('Number of majors: ' + this._majors.length);
            console.log('Number of students: ' + this.getNumberOfStudents());

            if (this._teachers.length > 0) {
                console.group('Teachers: ');
                this._teachers.forEach(teacher => {
                    teacher.printTeacher();
                });
                console.groupEnd();
            }

            if (this._majors.length > 0) {
                console.group('Majors: ');
                this._majors.forEach(major => {
                    major.printMajor();
                });
                console.groupEnd();
            }

            console.groupEnd();
        }
    }
} 

Education/Exam.ts

module Education {
    'use strict';

    export class Exam<T extends Interfaces.ITeacher, S extends Interfaces.IStudent> {
        private _majorType: string;
        private _discipline: string;
        private _teacher: T;
        private _students: S[];

        constructor(majorType: string, discipline: string, teacher: T, students: S[]) {
            this.majorType = majorType;
            this.discipline = discipline;
            this._teacher = teacher;

            if (students) {
                this._students = students;
            }
            else {
                this._students = [];
            }
        }

        public get majorType(): string {
            return this._majorType;
        }

        public set majorType(majorType: string) {
            if (!Education.MajorType.isMajorTypeValid(majorType)) {
                throw new Error('There is no such major type!');
            }

            this._majorType = majorType;
        }

        public get discipline(): string {
            return this._discipline;
        }

        public set discipline(discipline: string) {
            if (!Education.Discipline.isDisciplineValid(discipline)) {
                throw new Error('There is no such discipline!');
            }

            this._discipline = discipline;
        }

        public get teacher(): T {
            return this._teacher;
        }

        public get students(): S[] {
            return this._students;
        }

        public printExam(): void {
            console.group('Exam: ');
            console.log('Major: ' + this._majorType + ', Discipline: ' + this._discipline);
            console.log('Teacher: ');
            this._teacher.printTeacher();
            console.log('Students: ');

            this._students.forEach(student => {
                student.printStudent();
            });

            console.groupEnd();
        }
    }
} 
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s