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 strict;
use warnings; use warnings;
use utf8;
use Data::Dumper; use Data::Dumper;
@ -13,6 +14,8 @@ use JapaChar::Schema;
use Moo; use Moo;
use List::MoreUtils qw(uniq);
use Encode qw/decode/; use Encode qw/decode/;
has app => ( is => 'ro', required => 1 ); has app => ( is => 'ro', required => 1 );
@ -41,53 +44,59 @@ sub grades($self) {
return \@grades; return \@grades;
} }
sub get_4_incorrect_answers( $self, $char, $guess) { sub get_4_incorrect_answers( $self, $char, $guess ) {
if ($guess->isa('JapaChar::Schema::Result::KanjiMeanings')) { if ( $guess->isa('JapaChar::Schema::Result::KanjiMeanings') ) {
my %already_present_guesses; 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 $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', -bool => 'kanji.started',
meaning => { -not_in => $invalid_results }, meaning => { -not_in => $invalid_results },
}, },
{ {
order_by => { -asc => \'RANDOM()' }, order_by => { -asc => \'RANDOM()' },
rows => 4, rows => 4,
join => 'kanji', join => 'kanji',
} }
); );
return \@possible_meanings; return \@possible_meanings;
} }
if ($guess->isa('JapaChar::Schema::Result::KanjiOnReadings')) { if ( $guess->isa('JapaChar::Schema::Result::KanjiOnReadings') ) {
my %already_present_guesses; 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 $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', -bool => 'kanji.started',
reading => { -not_in => $invalid_results }, reading => { -not_in => $invalid_results },
}, },
{ {
order_by => { -asc => \'RANDOM()' }, order_by => { -asc => \'RANDOM()' },
rows => 4, rows => 4,
join => 'kanji', join => 'kanji',
} }
); );
return \@possible_readings; return \@possible_readings;
} }
if ($guess->isa('JapaChar::Schema::Result::KanjiKunReadings')) { if ( $guess->isa('JapaChar::Schema::Result::KanjiKunReadings') ) {
my %already_present_guesses; 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 $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', -bool => 'kanji.started',
reading => { -not_in => $invalid_results }, reading => { -not_in => $invalid_results },
}, },
{ {
order_by => { -asc => \'RANDOM()' }, order_by => { -asc => \'RANDOM()' },
rows => 4, rows => 4,
join => 'kanji', join => 'kanji',
} }
); );
return \@possible_readings; return \@possible_readings;
} }
} }
@ -134,6 +143,7 @@ sub populate_kanji( $self, $parent_pid, $write ) {
die 'Parent died'; die 'Parent died';
} }
my $literal = $character_dom->at('literal')->text; my $literal = $character_dom->at('literal')->text;
$literal = decode 'utf-8', $literal;
my $grade; my $grade;
my $grade_dom = $character_dom->at('grade'); my $grade_dom = $character_dom->at('grade');
if ( defined $grade_dom ) { if ( defined $grade_dom ) {
@ -146,14 +156,29 @@ sub populate_kanji( $self, $parent_pid, $write ) {
} }
my @readings_on; my @readings_on;
my @readings_kun; my @readings_kun;
my $die = 0;
binmode STDOUT, ':utf8';
for my $reading_dom ( $character_dom->find('reading')->each ) { 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' ) { 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' ) { 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, push @characters,
{ {
id => $i++, id => $i++,
@ -197,12 +222,11 @@ sub next_char( $self, $accesibility, $type = undef ) {
} }
sub _next_review_char( $self, $type = undef ) { sub _next_review_char( $self, $type = undef ) {
my $kanji_resultset = my $kanji_resultset = JapaChar::Schema->Schema->resultset('Kanji');
JapaChar::Schema->Schema->resultset('Kanji'); my @chars = $kanji_resultset->search(
my @chars = $kanji_resultset->search(
{ {
score => { '>=' => 300 }, score => { '>=' => 300 },
( ( $type ne 'all' ) ? ( grade => { is => $type} ) : () ) ( ( $type ne 'all' ) ? ( grade => { is => $type } ) : () )
}, },
{ {
order_by => { -asc => \'RANDOM()' }, order_by => { -asc => \'RANDOM()' },
@ -216,8 +240,7 @@ sub _next_review_char( $self, $type = undef ) {
} }
sub _next_learning_char( $self, $type = undef ) { sub _next_learning_char( $self, $type = undef ) {
my $kanji_resultset = my $kanji_resultset = JapaChar::Schema->Schema->resultset('Kanji');
JapaChar::Schema->Schema->resultset('Kanji');
my @candidate_chars = $self->_retrieve_started_chars_not_finished($type); my @candidate_chars = $self->_retrieve_started_chars_not_finished($type);
if ( @candidate_chars < 5 ) { if ( @candidate_chars < 5 ) {
my @new_chars = $kanji_resultset->search( my @new_chars = $kanji_resultset->search(
@ -226,7 +249,7 @@ sub _next_learning_char( $self, $type = undef ) {
( ( $type ne 'all' ) ? ( grade => { is => $type } ) : () ) ( ( $type ne 'all' ) ? ( grade => { is => $type } ) : () )
}, },
{ {
order_by => { -asc => ['grade', 'id'] }, order_by => { -asc => [ \'grade IS NULL', 'grade', 'id' ] },
rows => 5 - scalar @candidate_chars, rows => 5 - scalar @candidate_chars,
} }
); );
@ -240,8 +263,7 @@ sub _next_learning_char( $self, $type = undef ) {
} }
sub _retrieve_started_chars_not_finished( $self, $type ) { sub _retrieve_started_chars_not_finished( $self, $type ) {
my $kanji_resultset = my $kanji_resultset = JapaChar::Schema->Schema->resultset('Kanji');
JapaChar::Schema->Schema->resultset('Kanji');
return $kanji_resultset->search( return $kanji_resultset->search(
{ {
( ( $type ne 'all' ) ? ( grade => { is => $type } ) : () ), ( ( $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) { sub finish_lesson_screen($self) {
my $notable_lesson = $self->_successes >= 7; my $notable_lesson = $self->_successes >= 7 * 3;
my $feedback_label; my $feedback_label;
my $box = Gtk::Box->new( 'vertical', 10 ); my $box = Gtk::Box->new( 'vertical', 10 );
if ($notable_lesson) { if ($notable_lesson) {

View File

@ -77,11 +77,10 @@ sub run($self) {
$self->lesson->finish_lesson_screen(); $self->lesson->finish_lesson_screen();
return; return;
} }
my $rng = JapaChar::Random->new->get( 1, 100 );
my $char = my $char =
$self->_app->kanji->next_char( $self->_app->accessibility, $self->_type ); $self->_app->kanji->next_char( $self->_app->accessibility, $self->_type );
my @available_guessses = ($char->meanings, $char->on_readings, $char->kun_readings); 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]); $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 ); my $kanji_label = $self->_get_label_featured_character( $char->kanji );
$kanji_label->set_halign('center'); $kanji_label->set_halign('center');
$kanji_label->set_valign('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 ); my $box_kanji = Gtk::Box->new( 'vertical', 10 );
$box_kanji->append( $self->_new_exercise_number_label ); $box_kanji->append( $self->_new_exercise_number_label );
$box_kanji->append($kanji_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); $self->_app->window_set_child($grid);
my $back_button = $self->lesson->create_exit_lesson_back_button( my $back_button = $self->lesson->create_exit_lesson_back_button(
sub { sub {

View File

@ -5,3 +5,22 @@ headerbar box {
button { button {
min-width: 0; 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;
}