src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

category.go (2360B)


      1 package category
      2 
      3 import (
      4 	"fmt"
      5 
      6 	"code.dwrz.net/src/pkg/color"
      7 	"code.dwrz.net/src/pkg/dqs/portion"
      8 )
      9 
     10 type Category struct {
     11 	Name        string            `json:"name"`
     12 	Portions    []portion.Portion `json:"portions"`
     13 	HighQuality bool              `json:"highQuality"`
     14 }
     15 
     16 func (c *Category) Add(q float64) error {
     17 	for i := range c.Portions {
     18 		p := &c.Portions[i]
     19 		// Done if there's less than a half-portion left.
     20 		if q < 0.5 {
     21 			break
     22 		}
     23 
     24 		switch p.Amount {
     25 		case portion.Full:
     26 			continue
     27 		case portion.Half:
     28 			p.Amount = portion.Full
     29 			q -= 0.5
     30 		case portion.None:
     31 			if q >= 1.0 {
     32 				p.Amount = portion.Full
     33 				q -= 1.0
     34 			} else if q >= 0.5 {
     35 				p.Amount = portion.Half
     36 				q -= 0.5
     37 			}
     38 		}
     39 	}
     40 
     41 	// Check if we were able to add all the portions.
     42 	if q > 0.5 {
     43 		return fmt.Errorf("too many portions of %s", c.Name)
     44 	}
     45 
     46 	return nil
     47 }
     48 
     49 func (c *Category) Score() (total float64) {
     50 	for _, p := range c.Portions {
     51 		total += p.Score()
     52 	}
     53 
     54 	return total
     55 }
     56 
     57 func (c *Category) FormatPrint() string {
     58 	var str = fmt.Sprintf("ā”‚%-26sā”‚", c.Name)
     59 
     60 	for _, p := range c.Portions {
     61 		var cellColor color.Color
     62 
     63 		switch {
     64 		case p.Points > 0 && p.Amount == portion.Full:
     65 			cellColor = color.BackgroundBrightGreen
     66 		case p.Points > 0 && p.Amount == portion.Half:
     67 			cellColor = color.BrightGreen
     68 		case p.Points == 0 && p.Amount == portion.Full:
     69 			cellColor = color.BackgroundBrightYellow
     70 		case p.Points == 0 && p.Amount == portion.Half:
     71 			cellColor = color.BrightYellow
     72 		case p.Points < 0 && p.Amount == portion.Full:
     73 			cellColor = color.BackgroundBrightRed
     74 		case p.Points < 0 && p.Amount == portion.Half:
     75 			cellColor = color.BrightRed
     76 		}
     77 
     78 		str += fmt.Sprintf("%s%+d%sā”‚", cellColor, p.Points, color.Reset)
     79 	}
     80 
     81 	return str
     82 }
     83 
     84 func (c *Category) Remove(q float64) error {
     85 	for i := len(c.Portions) - 1; i >= 0; i-- {
     86 		p := &c.Portions[i]
     87 		// Done if there's less than a half-portion left.
     88 		if q < 0.5 {
     89 			break
     90 		}
     91 
     92 		switch p.Amount {
     93 		case portion.None:
     94 			continue
     95 		case portion.Half:
     96 			p.Amount = portion.None
     97 			q -= 0.5
     98 		case portion.Full:
     99 			if q >= 1.0 {
    100 				p.Amount = portion.None
    101 				q -= 1.0
    102 			} else if q >= 0.5 {
    103 				p.Amount = portion.Half
    104 				q -= 0.5
    105 			}
    106 		}
    107 	}
    108 
    109 	// Check if we were able to remove all the portions.
    110 	if q > 0.5 {
    111 		return fmt.Errorf("too many portions of %s", c.Name)
    112 	}
    113 
    114 	return nil
    115 }