Grades

 view release on metacpan or  search on metacpan

lib/Grades.pm  view on Meta::CPAN

=cut

	has 'id' => (is => 'ro', isa => 'Str', required => 1);

=head3 yaml

The content of the league configuration file.

=cut

	has 'yaml' => (is => 'ro', isa => 'HashRef', lazy_build => 1);
	method _build_yaml {
			my $leaguedirs = $self->leagues;
			my $league = $self->id;
			$self->inspect( "$leaguedirs/$league/league.yaml" );
	}

=head3 name

The name of the league (class).

lib/Grades.pm  view on Meta::CPAN

		my $data = $self->yaml;
		$data->{member};
	}

=head3 session

The first week in each session, like { 1 => 1, 2 => 5, 3 => 10, 4 => 14 }, monotonically increasing week numbers.

=cut

	has 'session', (is => 'ro', isa => 'HashRef',
	    lazy => 1, default => sub { shift->yaml->{session} } );


=head3 absentees

Students who have stopped coming to class and so won't be included in classwork scoring.

=cut

	has 'absentees', (is => 'ro', isa => PlayerNames,

lib/Grades.pm  view on Meta::CPAN



=head3 transfer

    $oldleague = $newleague->transfer->{V9731059}

Players who have transferred to this league from some other league at some point and the leagues they transferred from.

=cut

	has 'transfer', (is => 'ro', isa => 'HashRef',
	    lazy => 1, default => sub { shift->yaml->{transfer} } );


=head3 is_member

Whether the passed id is that of a member in the league (class).

=cut

	method is_member (Str $id) {

lib/Grades.pm  view on Meta::CPAN

	my $basename = shift->league->yaml->{hw} || "exams";
	my $hwdir = $leaguedir . '/' . $basename;
    }

=head3 rounds

An arrayref of the rounds for which there are homework grades for players in the league, in round order, of the form, [1, 3 .. 7, 9 ..].

=cut

	has 'rounds', (is => 'ro', isa => 'ArrayRef[Int]', lazy_build => 1);
	method _build_rounds {
		my $hwdir = $self->hwdir;
		my @hw = glob "$hwdir/*.yaml";
		[ sort {$a<=>$b} map m/^$hwdir\/(\d+)\.yaml$/, @hw ];
	}

=head3 roundIndex

Given a round name (ie number), returns the ordinal position in which this round was played, with the first round numbered 0. Returns undef if the round was not played.

lib/Grades.pm  view on Meta::CPAN

			$n++;
		}
	}

=head3 roundfiles

An hashref of the files with data for the rounds for which there are homework grades for players in the league, keyed on rounds.

=cut

	has 'roundfiles', (is => 'ro', isa => 'HashRef[ArrayRef]', lazy_build => 1);
	method _build_roundfiles {
		my $hwdir = $self->hwdir;
		my @hw = glob "$hwdir/*.yaml";
		my @rounds = map m/^$hwdir\/(\d+)\.yaml$/, @hw;
		+{ map { $_ => [ glob "$hwdir/${_}*.yaml" ] } @rounds }
	}

=head3 hwbyround 

A hashref of the homework grades for players in the league for each round.

lib/Grades.pm  view on Meta::CPAN

		my $groups = $self->jigsawGroups( $jigsaw );
		my $members = $groups->{$group};
	}

=head3 roles

At the moment, just A .. D.

=cut

	has 'roles' => (is => 'ro', isa => 'ArrayRef[Str]',
	    default => sub { [ qw/A B C D/ ] } );


=head3 idsbyRole

Ids in array, in A-D role order

=cut


lib/Grades.pm  view on Meta::CPAN

	my $groupworkdirs = $leaguedir .'/' . $basename;
	}

=head3 series

The sessions (weeks) over the series (semester) in each of which there was a different grouping and results of players. This method returns an arrayref of the names (numbers) of the sessions, in numerical order, of the form, [1, 3 .. 7, 9, 10 .. 99 ]...

=cut

    has 'series' =>
      ( is => 'ro', isa => 'Maybe[ArrayRef[Int]]', lazy_build => 1 );
    method _build_series {
        my $dir = $self->groupworkdirs;
        my @subdirs = grep { -d } glob "$dir/*";
        [ sort { $a <=> $b } map m/^$dir\/(\d+)$/, @subdirs ];
    }

#=head3 all_events
#
#All the weeks, or sessions or lessons for which grade data is being assembled from for the grade component.
#

lib/Grades.pm  view on Meta::CPAN

	my $compcompdir = $leaguedir .'/' . shift->league->yaml->{compcomp};
    }

=head3 all_events

The pair conversations over the series (semester). This method returns an arrayref of the numbers of the conversations, in numerical order, of the form, [1, 3 .. 7, 9, 10 .. 99 ]. Results are in sub directories of the same name, under compcompdirs.

=cut

    has 'all_events' =>
      ( is => 'ro', isa => 'Maybe[ArrayRef[Int]]', lazy_build => 1 );
    method _build_all_events {
        my $dir = $self->compcompdirs;
        my @subdirs = grep { -d } glob "$dir/*";
        [ sort { $a <=> $b } map m/^$dir\/(\d+)$/, @subdirs ];
    }

=head3 config

The round.yaml file with data about the Compcomp activity for the given conversation (directory.)

lib/Grades.pm  view on Meta::CPAN

	my $examdirs = $leaguedir .'/' . $basename;
    }

=head3 examids

An arrayref of the ids of the exams for which there are grades for players in the league, in numerical order, of the form, [1, 3 .. 7, 9, 10 .. 99 ]. Results are in sub directories of the same name, under examdir.

=cut

    has 'examids',
      ( is => 'ro', isa => 'Maybe[ArrayRef[Int]]', lazy_build => 1 );
    method _build_examids {
        my $examdirs = $self->examdirs;
        my @exams   = grep { -d } glob "$examdirs/[0-9] $examdirs/[1-9][0-9]";
        [ sort { $a <=> $b } map m/^$examdirs\/(\d+)$/, @exams ];
    }

=head3 examrounds

The rounds over which the given exam was conducted. Should be an array ref. If there were no rounds, ie the exam was conducted in one round, a null anonymous array is returned. The results for the rounds are in sub directories underneath the 'examid'...

lib/Grades.pm  view on Meta::CPAN

"Exam $id probably has undefined or non-numeric Exam scores, or possibly illegal PlayerIds." ;
	    }
	}

=head3 examResults

A hash ref of the ids of the players and arrays of their results over the exam series, ie examids, in files named 'g.yaml', TODO but only if such a file exists in all examdirs. Otherwise, calculate from raw 'response.yaml' files. Croak if any result ...

=cut

    has 'examResults' => ( is => 'ro', isa => 'HashRef', lazy_build => 1 );
    method _build_examResults {
        my $examids = $self->examids;
	my $members = $self->league->members;
	my @playerids = map { $_->{id} } @$members;
	my %results;
	for my $id  ( @$examids ) {
	    my $exam    = $self->exam( $id );
	    my $max      = $self->examMax;
	    for my $playerid ( @playerids ) {
		my $result = $exam->{$playerid};

lib/Grades.pm  view on Meta::CPAN

	}
	return \%results;
    }

=head3 examResultHash

A hash ref of the ids of the players and hashrefs of their results for each exam. Croak if any result is larger than examMax.

=cut

	has 'examResultHash' => (is => 'ro', isa => 'HashRef', lazy_build => 1);
	method _build_examResultHash {
		my $examids = $self->examids;
		my $examResults = $self->examResults;
		my %examResults;
		for my $id ( keys %$examResults ) {
			my $results = $examResults->{$id};
			my %results;
			@results{@$examids} = @$results;
			$examResults{$id} = \%results;
		}
		return \%examResults;
	}

=head3 examResultsasPercent

A hashref of the ids of the players and arrays of their results over the exams expressed as percentages of the maximum possible score for the exams.

=cut

	has 'examResultsasPercent' => (is=>'ro', isa=>'HashRef', lazy_build=>1);
	method _build_examResultsasPercent {
		my $scores = $self->examResults;
		my @ids = keys %$scores;
		my $max = $self->examMax;
		my %percent =  map { my $id = $_; my $myscores = $scores->{$id};
		    $id => [ map { ($_||0) * (100/$max) } @$myscores ] } @ids;
		return \%percent;
	}

=head3 examGrade

A hash ref of the ids of the players and their total scores on exams.

=cut

	has 'examGrade' => (is => 'ro', isa => 'HashRef', lazy_build => 1);
	method _build_examGrade {
		my $grades = $self->examResults;
		+{ map { my $numbers=$grades->{$_};
			$_ => sum(@$numbers) }
					keys %$grades };
	}

=head3 examPercent

A hash ref of the ids of the players and their total score on exams, expressed as a percentage of the possible exam score. This is the average of their exam scores.

=cut

    has 'examPercent' => (is => 'ro', isa => 'HashRef', lazy_build => 1);
    method _build_examPercent {
	my $grades = $self->examResultsasPercent;
	my %totals = map {
		my $numbers=$grades->{$_};
		$_ => sum(@$numbers)/@{$numbers} } keys %$grades;
	return \%totals;
    }

}

lib/Grades.pm~  view on Meta::CPAN

=cut

	has 'id' => (is => 'ro', isa => 'Str', required => 1);

=head3 yaml

The content of the league configuration file.

=cut

	has 'yaml' => (is => 'ro', isa => 'HashRef', lazy_build => 1);
	method _build_yaml {
			my $leaguedirs = $self->leagues;
			my $league = $self->id;
			$self->inspect( "$leaguedirs/$league/league.yaml" );
	}

=head3 name

The name of the league (class).

lib/Grades.pm~  view on Meta::CPAN

		my $data = $self->yaml;
		$data->{member};
	}

=head3 session

The first week in each session, like { 1 => 1, 2 => 5, 3 => 10, 4 => 14 }, monotonically increasing week numbers.

=cut

	has 'session', (is => 'ro', isa => 'HashRef',
	    lazy => 1, default => sub { shift->yaml->{session} } );


=head3 absentees

Students who have stopped coming to class and so won't be included in classwork scoring.

=cut

	has 'absentees', (is => 'ro', isa => PlayerNames,

lib/Grades.pm~  view on Meta::CPAN



=head3 transfer

    $oldleague = $newleague->transfer->{V9731059}

Players who have transferred to this league from some other league at some point and the leagues they transferred from.

=cut

	has 'transfer', (is => 'ro', isa => 'HashRef',
	    lazy => 1, default => sub { shift->yaml->{transfer} } );


=head3 is_member

Whether the passed id is that of a member in the league (class).

=cut

	method is_member (Str $id) {

lib/Grades.pm~  view on Meta::CPAN

	my $basename = shift->league->yaml->{hw} || "exams";
	my $hwdir = $leaguedir . '/' . $basename;
    }

=head3 rounds

An arrayref of the rounds for which there are homework grades for players in the league, in round order, of the form, [1, 3 .. 7, 9 ..].

=cut

	has 'rounds', (is => 'ro', isa => 'ArrayRef[Int]', lazy_build => 1);
	method _build_rounds {
		my $hwdir = $self->hwdir;
		my @hw = glob "$hwdir/*.yaml";
		[ sort {$a<=>$b} map m/^$hwdir\/(\d+)\.yaml$/, @hw ];
	}

=head3 roundIndex

Given a round name (ie number), returns the ordinal position in which this round was played, with the first round numbered 0. Returns undef if the round was not played.

lib/Grades.pm~  view on Meta::CPAN

			$n++;
		}
	}

=head3 roundfiles

An hashref of the files with data for the rounds for which there are homework grades for players in the league, keyed on rounds.

=cut

	has 'roundfiles', (is => 'ro', isa => 'HashRef[ArrayRef]', lazy_build => 1);
	method _build_roundfiles {
		my $hwdir = $self->hwdir;
		my @hw = glob "$hwdir/*.yaml";
		my @rounds = map m/^$hwdir\/(\d+)\.yaml$/, @hw;
		+{ map { $_ => [ glob "$hwdir/${_}*.yaml" ] } @rounds }
	}

=head3 hwbyround 

A hashref of the homework grades for players in the league for each round.

lib/Grades.pm~  view on Meta::CPAN

		my $groups = $self->jigsawGroups( $jigsaw );
		my $members = $groups->{$group};
	}

=head3 roles

At the moment, just A .. D.

=cut

	has 'roles' => (is => 'ro', isa => 'ArrayRef[Str]',
	    default => sub { [ qw/A B C D/ ] } );


=head3 idsbyRole

Ids in array, in A-D role order

=cut


lib/Grades.pm~  view on Meta::CPAN

	my $groupworkdirs = $leaguedir .'/' . $basename;
	}

=head3 series

The sessions (weeks) over the series (semester) in each of which there was a different grouping and results of players. This method returns an arrayref of the names (numbers) of the sessions, in numerical order, of the form, [1, 3 .. 7, 9, 10 .. 99 ]...

=cut

    has 'series' =>
      ( is => 'ro', isa => 'Maybe[ArrayRef[Int]]', lazy_build => 1 );
    method _build_series {
        my $dir = $self->groupworkdirs;
        my @subdirs = grep { -d } glob "$dir/*";
        [ sort { $a <=> $b } map m/^$dir\/(\d+)$/, @subdirs ];
    }

#=head3 all_events
#
#All the weeks, or sessions or lessons for which grade data is being assembled from for the grade component.
#

lib/Grades.pm~  view on Meta::CPAN

	my $compcompdir = $leaguedir .'/' . shift->league->yaml->{compcomp};
    }

=head3 all_events

The pair conversations over the series (semester). This method returns an arrayref of the numbers of the conversations, in numerical order, of the form, [1, 3 .. 7, 9, 10 .. 99 ]. Results are in sub directories of the same name, under compcompdirs.

=cut

    has 'all_events' =>
      ( is => 'ro', isa => 'Maybe[ArrayRef[Int]]', lazy_build => 1 );
    method _build_all_events {
        my $dir = $self->compcompdirs;
        my @subdirs = grep { -d } glob "$dir/*";
        [ sort { $a <=> $b } map m/^$dir\/(\d+)$/, @subdirs ];
    }

=head3 config

The round.yaml file with data about the Compcomp activity for the given conversation (directory.)

lib/Grades.pm~  view on Meta::CPAN

	my $examdirs = $leaguedir .'/' . $basename;
    }

=head3 examids

An arrayref of the ids of the exams for which there are grades for players in the league, in numerical order, of the form, [1, 3 .. 7, 9, 10 .. 99 ]. Results are in sub directories of the same name, under examdir.

=cut

    has 'examids',
      ( is => 'ro', isa => 'Maybe[ArrayRef[Int]]', lazy_build => 1 );
    method _build_examids {
        my $examdirs = $self->examdirs;
        my @exams   = grep { -d } glob "$examdirs/[0-9] $examdirs/[1-9][0-9]";
        [ sort { $a <=> $b } map m/^$examdirs\/(\d+)$/, @exams ];
    }

=head3 examrounds

The rounds over which the given exam was conducted. Should be an array ref. If there were no rounds, ie the exam was conducted in one round, a null anonymous array is returned. The results for the rounds are in sub directories underneath the 'examid'...

lib/Grades.pm~  view on Meta::CPAN

"Exam $id probably has undefined or non-numeric Exam scores, or possibly illegal PlayerIds." ;
	    }
	}

=head3 examResults

A hash ref of the ids of the players and arrays of their results over the exam series, ie examids, in files named 'g.yaml', TODO but only if such a file exists in all examdirs. Otherwise, calculate from raw 'response.yaml' files. Croak if any result ...

=cut

    has 'examResults' => ( is => 'ro', isa => 'HashRef', lazy_build => 1 );
    method _build_examResults {
        my $examids = $self->examids;
	my $members = $self->league->members;
	my @playerids = map { $_->{id} } @$members;
	my %results;
	for my $id  ( @$examids ) {
	    my $exam    = $self->exam( $id );
	    my $max      = $self->examMax;
	    for my $playerid ( @playerids ) {
		my $result = $exam->{$playerid};

lib/Grades.pm~  view on Meta::CPAN

	}
	return \%results;
    }

=head3 examResultHash

A hash ref of the ids of the players and hashrefs of their results for each exam. Croak if any result is larger than examMax.

=cut

	has 'examResultHash' => (is => 'ro', isa => 'HashRef', lazy_build => 1);
	method _build_examResultHash {
		my $examids = $self->examids;
		my $examResults = $self->examResults;
		my %examResults;
		for my $id ( keys %$examResults ) {
			my $results = $examResults->{$id};
			my %results;
			@results{@$examids} = @$results;
			$examResults{$id} = \%results;
		}
		return \%examResults;
	}

=head3 examResultsasPercent

A hashref of the ids of the players and arrays of their results over the exams expressed as percentages of the maximum possible score for the exams.

=cut

	has 'examResultsasPercent' => (is=>'ro', isa=>'HashRef', lazy_build=>1);
	method _build_examResultsasPercent {
		my $scores = $self->examResults;
		my @ids = keys %$scores;
		my $max = $self->examMax;
		my %percent =  map { my $id = $_; my $myscores = $scores->{$id};
		    $id => [ map { ($_||0) * (100/$max) } @$myscores ] } @ids;
		return \%percent;
	}

=head3 examGrade

A hash ref of the ids of the players and their total scores on exams.

=cut

	has 'examGrade' => (is => 'ro', isa => 'HashRef', lazy_build => 1);
	method _build_examGrade {
		my $grades = $self->examResults;
		+{ map { my $numbers=$grades->{$_};
			$_ => sum(@$numbers) }
					keys %$grades };
	}

=head3 examPercent

A hash ref of the ids of the players and their total score on exams, expressed as a percentage of the possible exam score. This is the average of their exam scores.

=cut

    has 'examPercent' => (is => 'ro', isa => 'HashRef', lazy_build => 1);
    method _build_examPercent {
	my $grades = $self->examResultsasPercent;
	my %totals = map {
		my $numbers=$grades->{$_};
		$_ => sum(@$numbers)/@{$numbers} } keys %$grades;
	return \%totals;
    }

}

lib/Grades/Groupwork.pm  view on Meta::CPAN


	method beancan_names (Str $session) { $self->beancanseries->{$session}; }

=head3 allfiles

The files (unsorted) containing classwork points (beans) awarded to beancans, of form, groupworkdir/\d+\.yaml$

=cut


	has 'allfiles'  => ( is => 'ro', isa => 'ArrayRef', lazy_build => 1 );
	method _build_allfiles {
		my $dir = $self->groupworkdirs;
		my $series = $self->series;
		my $league = $self->league->id;
		my $files = [ grep m|/(\d+)\.yaml$|, glob "$dir/*.yaml"];
		croak "${league}'s @$series session files: @$files?" unless @$files;
		return $files;
	}

=head3 all_ided_files

The files containing classwork points (beans) awarded to beancans, of form, groupworkdir/\d+\.yaml$ keyed on the \d+.

=cut


	has 'all_ided_files'  => ( is => 'ro', isa => 'HashRef', lazy_build => 1 );
	method _build_all_ided_files {
		my $files = $self->allfiles;
		my %files = map { m|/(\d+)\.yaml$|; $1 => $_ } @$files;
		croak "No classwork files: $files?" unless %files;
		return \%files;
	}

=head3 all_events

The events (an array ref of integers) in which beans were awarded.

=cut

	has 'all_events' => ( is => 'ro', isa => 'ArrayRef', lazy_build => 1 );
	method _build_all_events {
		my $files = $self->all_ided_files;
		my @events = sort { $a <=> $b } keys %$files;
		croak "No classwork weeks: @events" unless @events;
		return \@events;
	}

=head3 lastweek

The last week in which beans were awarded. TODO lexicographic order, not numerical order.

lib/Grades/Groupwork.pm  view on Meta::CPAN

		my $weeks = $self->all_events;
		max @$weeks;
	}

=head3 data

The beans awarded to the beancans in the individual cards over the weeks of the series (semester.)

=cut

	has 'data' => (is => 'ro', isa => 'HashRef', lazy_build => 1);
	method _build_data {
		my $files = $self->all_ided_files;
		+{ map { $_ => $self->inspect( $files->{$_} ) } keys %$files };
	}

=head3 card

Classwork beans for each beancan for the given week

=cut

lib/Grades/Groupwork.pm~  view on Meta::CPAN


	method beancan_names (Str $session) { $self->beancanseries->{$session}; }

=head3 allfiles

The files (unsorted) containing classwork points (beans) awarded to beancans, of form, groupworkdir/\d+\.yaml$

=cut


	has 'allfiles'  => ( is => 'ro', isa => 'ArrayRef', lazy_build => 1 );
	method _build_allfiles {
		my $dir = $self->groupworkdirs;
		my $series = $self->series;
		my $league = $self->league->id;
		my $files = [ grep m|/(\d+)\.yaml$|, glob "$dir/*.yaml"];
		croak "${league}'s @$series session files: @$files?" unless @$files;
		return $files;
	}

=head3 all_ided_files

The files containing classwork points (beans) awarded to beancans, of form, groupworkdir/\d+\.yaml$ keyed on the \d+.

=cut


	has 'all_ided_files'  => ( is => 'ro', isa => 'HashRef', lazy_build => 1 );
	method _build_all_ided_files {
		my $files = $self->allfiles;
		my %files = map { m|/(\d+)\.yaml$|; $1 => $_ } @$files;
		croak "No classwork files: $files?" unless %files;
		return \%files;
	}

=head3 all_events

The events (an array ref of integers) in which beans were awarded.

=cut

	has 'all_events' => ( is => 'ro', isa => 'ArrayRef', lazy_build => 1 );
	method _build_all_events {
		my $files = $self->all_ided_files;
		my @events = sort { $a <=> $b } keys %$files;
		croak "No classwork weeks: @events" unless @events;
		return \@events;
	}

=head3 lastweek

The last week in which beans were awarded. TODO lexicographic order, not numerical order.

lib/Grades/Groupwork.pm~  view on Meta::CPAN

		my $weeks = $self->all_events;
		max @$weeks;
	}

=head3 data

The beans awarded to the beancans in the individual cards over the weeks of the series (semester.)

=cut

	has 'data' => (is => 'ro', isa => 'HashRef', lazy_build => 1);
	method _build_data {
		my $files = $self->all_ided_files;
		+{ map { $_ => $self->inspect( $files->{$_} ) } keys %$files };
	}

=head3 card

Classwork beans for each beancan for the given week

=cut



( run in 0.665 second using v1.01-cache-2.11-cpan-5f2e87ce722 )