package Ġcom . cr ave food . cr av ec al cul ator Ċ Ċ import Ġandroid . util . Log Ċ import Ġandroidx . lifecycle . Mutable LiveData Ċ import Ġandroidx . lifecycle . ViewModel Ċ import Ġnet . object h unter . exp 4 j . Expression Builder Ċ import Ġjava . text . Decimal Format Symbols Ċ Ċ const Ġval ĠNUMBER _ 0 Ġ= Ġ 0 Ċ const Ġval ĠNUMBER _ 1 Ġ= Ġ 1 Ċ const Ġval ĠNUMBER _ 2 Ġ= Ġ 2 Ċ const Ġval ĠNUMBER _ 3 Ġ= Ġ 3 Ċ const Ġval ĠNUMBER _ 4 Ġ= Ġ 4 Ċ const Ġval ĠNUMBER _ 5 Ġ= Ġ 5 Ċ const Ġval ĠNUMBER _ 6 Ġ= Ġ 6 Ċ const Ġval ĠNUMBER _ 7 Ġ= Ġ 7 Ċ const Ġval ĠNUMBER _ 8 Ġ= Ġ 8 Ċ const Ġval ĠNUMBER _ 9 Ġ= Ġ 9 Ċ const Ġval ĠOPER ATOR _ DI VID E Ġ= Ġ"/" Ċ const Ġval ĠOPER ATOR _ TIMES Ġ= Ġ"*" Ċ const Ġval ĠOPER ATOR _ MINUS Ġ= Ġ"-" Ċ const Ġval ĠOPER ATOR _ PLUS Ġ= Ġ" +" Ċ Ċ class ĠCalculator ViewModel Ġ: ĠViewModel () Ġ{ ĊĊĠĠĠ Ġval Ġdecimal Separator Ġ= ĠDecimal Format Symbols . getInstance (). decimal Separator . toString () ĊĠĠĠ Ġval Ġresult Observable Ġ= ĠMutable LiveData < Double >() ĊĠĠĠ Ġval Ġcurrent Expression Observable Ġ= ĠMutable LiveData < String >() ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġresult Observable . value Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġcurrent Expression Observable . value Ġ= Ġ"" ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġis Number ( test : ĠString ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( test . isEmpty ()) Ġreturn Ġfalse ĊĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( test ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠNUMBER _ 0 . toString () Ġ-> Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ ĠNUMBER _ 1 . toString () Ġ-> Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ ĠNUMBER _ 2 . toString () Ġ-> Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ ĠNUMBER _ 3 . toString () Ġ-> Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ ĠNUMBER _ 4 . toString () Ġ-> Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ ĠNUMBER _ 5 . toString () Ġ-> Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ ĠNUMBER _ 6 . toString () Ġ-> Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ ĠNUMBER _ 7 . toString () Ġ-> Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ ĠNUMBER _ 8 . toString () Ġ-> Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ ĠNUMBER _ 9 . toString () Ġ-> Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġis Operator ( test : ĠString ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( test ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOPER ATOR _ DI VID E Ġ-> Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOPER ATOR _ TIMES Ġ-> Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOPER ATOR _ MINUS Ġ-> Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ ĠOPER ATOR _ PLUS Ġ-> Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcan Add Number (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Expression Observable . value Ġ== Ġnull Ġ-> Ġtrue Ġ// ĠIf Ġis Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Expression Observable . value ?. isEmpty () Ġ== Ġtrue Ġ-> Ġtrue Ġ// ĠIf Ġis Ġempty ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Number ( current Expression Observable . value ?. last (). toString ()) Ġ-> Ġtrue Ġ// ĠIf Ġthe Ġlast Ġindex Ġis Ġa Ġnumber ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Operator ( current Expression Observable . value ?. last (). toString ()) Ġ-> Ġtrue Ġ// ĠIf Ġthe Ġlast Ġindex Ġis Ġa Ġoperator ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Expression Observable . value ?. last (). toString () Ġ== Ġdecimal Separator Ġ-> Ġtrue Ġ// ĠIf Ġthe Ġlast Ġindex Ġis Ġa Ġseparator ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcan Add Operator (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Expression Observable . value Ġ== Ġnull Ġ-> Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Expression Observable . value Ġ== Ġ"" Ġ-> Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Number ( current Expression Observable . value !!. last (). toString ()) Ġ-> Ġtrue Ġ// ĠIf Ġthe Ġlast Ġindex Ġis Ġa Ġnumber ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcan Add Separator (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Expression Observable . value Ġ== Ġnull Ġ-> Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Expression Observable . value Ġ== Ġ"" Ġ-> Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Operator ( current Expression Observable . value !!. last (). toString ()) Ġ-> Ġfalse Ġ// ĠIf Ġthe Ġlast Ġindex Ġis Ġa Ġoperator ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlast Number Has Separator ( current Expression Observable . value Ġ?: Ġ"") Ġ-> Ġfalse Ġ// ĠIf Ġthe Ġlast Ġindex Ġis Ġa Ġoperator ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Number ( current Expression Observable . value !!. last (). toString ()) Ġ-> Ġtrue Ġ// ĠIf Ġthe Ġlast Ġindex Ġis Ġa Ġnumber ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġlast Number Has Separator ( test : ĠString ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġregex Ġ= ĠRegex ("[ + \\ - */ ]? ([ \\ d ., ]+ )\ $ ") ĊĠĠĠĠĠĠĠ Ġval Ġmatch Ġ= Ġregex . find ( test ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( match Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprecision Ġ= Ġmatch . value ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcount Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprecision . filter Ġ{ Ġit . toString () Ġ== Ġdecimal Separator Ġ}. count () Ġ// ĠCount Ġdecimal Separator Ġoccurrences ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġcount Ġ> Ġ 0 ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġlast Index Is Operator ( expression : ĠString ? Ġ= Ġnull ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġexpression Ġ!= Ġnull Ġ&& Ġexpression Ġ!= Ġ"" Ġ&& Ġis Operator ( expression . last (). toString ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġupdate Preview Result ( new Expression : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( new Expression . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! last Index Is Operator ( new Expression )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġevaluate Ġ= ĠExpression Builder ( replace Separator ( new Expression )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. evaluate () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult Observable . value Ġ= Ġ"% . 2 f ". format ( evaluate ). replace (",", Ġ". "). toDouble () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult Observable . value Ġ= Ġ 0 . 0 ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġupdate Current Expression ( new Expression : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcurrent Expression Observable . value Ġ= Ġnew Expression ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġreplace Separator ( expression : ĠString ) Ġ= Ġexpression . replace (",", Ġ". ") ĊĊĠĠĠ Ġfun Ġadd Number ( number : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( can Add Number ()) Ġ{ Ġ// ĠAdd Ġthe Ġnumber ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Expression Ġ= Ġ"${ current Expression Observable . value Ġ?: Ġ"" }$ number " ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Preview Result ( new Expression ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Current Expression ( new Expression ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e (" Exception ", Ġe . message ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġadd Operator ( operator : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcan Add Operator () Ġ-> Ġ{ Ġ// ĠAdd Ġthe Ġoperator ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Current Expression ("${ current Expression Observable . value Ġ?: Ġ"" }$ operator ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlast Index Is Operator ( current Expression Observable . value ) Ġ-> Ġ{ Ġ// ĠReplace Ġthe Ġlast Ġoperator Ġfor Ġthe Ġnew Ġoperator ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġnew Expression Ġ= Ġcurrent Expression Observable . value . toString () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnew Expression Ġ= Ġ"${ new Expression . substring ( 0 , Ġnew Expression . length Ġ- Ġ 1 )} $ operator " ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Current Expression ( new Expression ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġadd Separator () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( can Add Separator ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Current Expression ("${ current Expression Observable . value Ġ?: Ġ"" }$ decimal Separator ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġremove Last Index () Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġnew Expression Ġ= Ġcurrent Expression Observable . value ĊĠĠĠĠĠĠĠ Ġnew Expression Ġ= Ġif Ġ( new Expression Ġ!= Ġnull Ġ&& Ġnew Expression . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnew Expression . toString (). let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . substring ( 0 , Ġit . length Ġ- Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ"" ĊĊĠĠĠĠĠĠĠ Ġupdate Preview Result ( new Expression ) ĊĠĠĠĠĠĠĠ Ġupdate Current Expression ( new Expression ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġclear Expression () Ġ{ ĊĠĠĠĠĠĠĠ Ġupdate Preview Result ("") ĊĠĠĠĠĠĠĠ Ġupdate Current Expression ("") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget Result () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtotal Ġ= Ġresult Observable . value ĊĠĠĠĠĠĠĠ Ġif Ġ( total Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Preview Result ( total . toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Current Expression ( total . toString ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ