Fixing multiple errors related with reading presentation and parsing.

This commit is contained in:
Sergiotarxz 2024-11-27 13:42:38 +01:00
parent 9a89f97910
commit a8462b9bd7
4 changed files with 105 additions and 31 deletions

View File

@ -4,6 +4,7 @@ use v5.40.0;
use strict;
use warnings;
use utf8;
use Data::Dumper;
@ -13,6 +14,8 @@ use JapaChar::Schema;
use Moo;
use List::MoreUtils qw(uniq);
use Encode qw/decode/;
has app => ( is => 'ro', required => 1 );
@ -41,53 +44,59 @@ sub grades($self) {
return \@grades;
}
sub get_4_incorrect_answers( $self, $char, $guess) {
if ($guess->isa('JapaChar::Schema::Result::KanjiMeanings')) {
sub get_4_incorrect_answers( $self, $char, $guess ) {
if ( $guess->isa('JapaChar::Schema::Result::KanjiMeanings') ) {
my %already_present_guesses;
my $invalid_results = [map { $_->meaning } $char->meanings];
my $invalid_results = [ map { $_->meaning } $char->meanings ];
my $meanings_resultset = $self->_schema->resultset('KanjiMeanings');
my @possible_meanings = map { $_->meaning } $meanings_resultset->search({
my @possible_meanings =
map { $_->meaning } $meanings_resultset->search(
{
-bool => 'kanji.started',
meaning => { -not_in => $invalid_results },
},
{
order_by => { -asc => \'RANDOM()' },
rows => 4,
join => 'kanji',
join => 'kanji',
}
);
);
return \@possible_meanings;
}
if ($guess->isa('JapaChar::Schema::Result::KanjiOnReadings')) {
if ( $guess->isa('JapaChar::Schema::Result::KanjiOnReadings') ) {
my %already_present_guesses;
my $invalid_results = [map { $_->reading } $char->on_readings];
my $invalid_results = [ map { $_->reading } $char->on_readings ];
my $readings_resultset = $self->_schema->resultset('KanjiOnReadings');
my @possible_readings = map { decode 'utf-8', $_->reading } $readings_resultset->search({
my @possible_readings =
map { decode 'utf-8', $_->reading } $readings_resultset->search(
{
-bool => 'kanji.started',
reading => { -not_in => $invalid_results },
},
{
order_by => { -asc => \'RANDOM()' },
rows => 4,
join => 'kanji',
join => 'kanji',
}
);
);
return \@possible_readings;
}
if ($guess->isa('JapaChar::Schema::Result::KanjiKunReadings')) {
if ( $guess->isa('JapaChar::Schema::Result::KanjiKunReadings') ) {
my %already_present_guesses;
my $invalid_results = [map { $_->reading } $char->kun_readings];
my $invalid_results = [ map { $_->reading } $char->kun_readings ];
my $readings_resultset = $self->_schema->resultset('KanjiOnReadings');
my @possible_readings = map { decode 'utf-8', $_->reading } $readings_resultset->search({
my @possible_readings =
map { decode 'utf-8', $_->reading } $readings_resultset->search(
{
-bool => 'kanji.started',
reading => { -not_in => $invalid_results },
},
{
order_by => { -asc => \'RANDOM()' },
rows => 4,
join => 'kanji',
join => 'kanji',
}
);
);
return \@possible_readings;
}
}
@ -134,6 +143,7 @@ sub populate_kanji( $self, $parent_pid, $write ) {
die 'Parent died';
}
my $literal = $character_dom->at('literal')->text;
$literal = decode 'utf-8', $literal;
my $grade;
my $grade_dom = $character_dom->at('grade');
if ( defined $grade_dom ) {
@ -146,14 +156,29 @@ sub populate_kanji( $self, $parent_pid, $write ) {
}
my @readings_on;
my @readings_kun;
my $die = 0;
binmode STDOUT, ':utf8';
for my $reading_dom ( $character_dom->find('reading')->each ) {
my $reading = $reading_dom->text;
$reading = decode 'utf-8', $reading;
$reading =~ s/\..*?$//;
$reading =~ s/-//g;
$reading =~ s/^\s*(.*?)\s*$/$1/;
if ( $reading_dom->attr('r_type') eq 'ja_on' ) {
push @readings_on, { reading => $reading_dom->text, };
push @readings_on, { reading => $reading, };
}
if ( $reading_dom->attr('r_type') eq 'ja_kun' ) {
push @readings_on, { reading => $reading_dom->text, };
push @readings_kun, { reading => $reading, };
}
}
my %readings_on = map { $_->{reading} => $_ } @readings_on;
my %readings_kun = map { $_->{reading} => $_ } @readings_kun;
@readings_on = map { $readings_on{$_} }
sort { $a cmp $b } keys %readings_on;
@readings_kun = map { $readings_kun{$_} }
sort { $a cmp $b } keys %readings_kun;
push @characters,
{
id => $i++,
@ -197,12 +222,11 @@ sub next_char( $self, $accesibility, $type = undef ) {
}
sub _next_review_char( $self, $type = undef ) {
my $kanji_resultset =
JapaChar::Schema->Schema->resultset('Kanji');
my @chars = $kanji_resultset->search(
my $kanji_resultset = JapaChar::Schema->Schema->resultset('Kanji');
my @chars = $kanji_resultset->search(
{
score => { '>=' => 300 },
( ( $type ne 'all' ) ? ( grade => { is => $type} ) : () )
( ( $type ne 'all' ) ? ( grade => { is => $type } ) : () )
},
{
order_by => { -asc => \'RANDOM()' },
@ -216,8 +240,7 @@ sub _next_review_char( $self, $type = undef ) {
}
sub _next_learning_char( $self, $type = undef ) {
my $kanji_resultset =
JapaChar::Schema->Schema->resultset('Kanji');
my $kanji_resultset = JapaChar::Schema->Schema->resultset('Kanji');
my @candidate_chars = $self->_retrieve_started_chars_not_finished($type);
if ( @candidate_chars < 5 ) {
my @new_chars = $kanji_resultset->search(
@ -226,7 +249,7 @@ sub _next_learning_char( $self, $type = undef ) {
( ( $type ne 'all' ) ? ( grade => { is => $type } ) : () )
},
{
order_by => { -asc => ['grade', 'id'] },
order_by => { -asc => [ \'grade IS NULL', 'grade', 'id' ] },
rows => 5 - scalar @candidate_chars,
}
);
@ -240,8 +263,7 @@ sub _next_learning_char( $self, $type = undef ) {
}
sub _retrieve_started_chars_not_finished( $self, $type ) {
my $kanji_resultset =
JapaChar::Schema->Schema->resultset('Kanji');
my $kanji_resultset = JapaChar::Schema->Schema->resultset('Kanji');
return $kanji_resultset->search(
{
( ( $type ne 'all' ) ? ( grade => { is => $type } ) : () ),

View File

@ -166,7 +166,7 @@ sub _on_dialog_exit_lesson_response( $self, $response, $on_exit ) {
}
sub finish_lesson_screen($self) {
my $notable_lesson = $self->_successes >= 7;
my $notable_lesson = $self->_successes >= 7 * 3;
my $feedback_label;
my $box = Gtk::Box->new( 'vertical', 10 );
if ($notable_lesson) {

View File

@ -77,11 +77,10 @@ sub run($self) {
$self->lesson->finish_lesson_screen();
return;
}
my $rng = JapaChar::Random->new->get( 1, 100 );
my $char =
$self->_app->kanji->next_char( $self->_app->accessibility, $self->_type );
my @available_guessses = ($char->meanings, $char->on_readings, $char->kun_readings);
$rng = JapaChar::Random->new->get( 0, scalar(@available_guessses) - 1 );
my $rng = JapaChar::Random->new->get( 0, scalar(@available_guessses) - 1 );
$self->_create_challenge($char, $available_guessses[$rng]);
}
@ -95,10 +94,44 @@ sub _create_challenge($self, $char, $guess) {
my $kanji_label = $self->_get_label_featured_character( $char->kanji );
$kanji_label->set_halign('center');
$kanji_label->set_valign('center');
my $exercise_type;
my $exercise_type_class;
my @helpers;
if ($guess->isa('JapaChar::Schema::Result::KanjiMeanings')) {
$exercise_type = 'Meaning';
$exercise_type_class = 'meaning';
@helpers = ('on_readings', 'kun_readings');
}
if ($guess->isa('JapaChar::Schema::Result::KanjiOnReadings')) {
$exercise_type = 'On';
$exercise_type_class = 'on-reading';
@helpers = ('meanings', 'kun_readings');
}
if ($guess->isa('JapaChar::Schema::Result::KanjiKunReadings')) {
$exercise_type = 'Kun';
$exercise_type_class = 'kun-reading';
@helpers = ('meanings', 'on_readings');
}
my $exercise_label = Gtk::Label->new($exercise_type);
$exercise_label->add_css_class('exercise_type');
$exercise_label->add_css_class($exercise_type_class);
$exercise_label->set_halign('center');
my $box_kanji = Gtk::Box->new( 'vertical', 10 );
$box_kanji->append( $self->_new_exercise_number_label );
$box_kanji->append($kanji_label);
$grid->attach( $box_kanji, 0, 0, 12, 1 );
$box_kanji->append($exercise_label);
for my $helper (@helpers) {
my $result;
{
if ($helper eq 'meanings') {
$result = join ', ', map {decode 'utf-8', $_->meaning} $char->can($helper)->($char);
next
}
$result = join ', ', map {decode 'utf-8', $_->reading} $char->can($helper)->($char);
}
$box_kanji->append(Gtk::Label->new("$helper: $result"));
}
$grid->attach( $box_kanji, 0, 0, 12, 4 );
$self->_app->window_set_child($grid);
my $back_button = $self->lesson->create_exit_lesson_back_button(
sub {

View File

@ -5,3 +5,22 @@ headerbar box {
button {
min-width: 0;
}
label.exercise_type {
padding: 10px;
border-radius: 10px;
font-weight: bold;
color: white;
}
label.on-reading {
background: red;
}
label.kun-reading {
background: blue;
}
label.meaning {
background: green;
}