packages feed

side-hustle-hourly (empty) → 0.1.0

raw patch · 4 files changed

+96/−0 lines, 4 filesdep +base

Dependencies added: base

Files

+ CHANGELOG.md view
@@ -0,0 +1,5 @@+# Change log++## 0.1.0++* Initial release: netCash, hourlyRate, compareGigs.
+ README.md view
@@ -0,0 +1,26 @@+# side-hustle-hourly++True hourly rate math for side hustles and gig work.++A gig's posted rate counts gross cash over paid hours. The real rate+takes the platform cut and the costs of each job off the gross first,+then divides by hours that include the unpaid admin around the paid+ones. Messaging a client, invoicing, restocking supplies, the drive to+the job: none of it bills, and all of it lands on the same denominator.++The package follows the effective-hourly-rate method used on+[Extra Hustles](https://extrahustles.com). It depends only on base.++## Example++A gig pays $200 gross, the platform keeps 15 percent, supplies run+$40, the paid block is 5 hours, and admin eats 3 more:++* net cash: `netCash 200 0.15 40` = $130+* true hourly rate: `hourlyRate 130 5 3` = $16.25+* the same net with zero admin hours: $26 an hour++That last number is the trap. The two rates describe the same gig, and+`compareGigs 16.25 12.00` says a second gig paying $12 an hour on an+honest denominator still loses to this one by $4.25 an hour. Compare+rates on hours that count everything, or the comparison is fiction.
+ side-hustle-hourly.cabal view
@@ -0,0 +1,34 @@+cabal-version:      2.2+name:               side-hustle-hourly+version:            0.1.0+synopsis:           True hourly rate math for side hustles and gig work+description:+  The rate a gig actually pays: the platform cut and job costs come off+  the gross first, and the net divides by hours that include the unpaid+  admin work around the paid ones. Two gigs compare on that rate, and+  the gap between them is the per-hour price of picking the wrong one.+  .+  Companion to Extra Hustles, which prices gig work by its effective+  hourly rate after hidden costs. Three pure functions on Doubles, no+  dependencies beyond base.+license:            MIT+author:             Poket Dev+maintainer:         hello@poketdev.com+homepage:           https://extrahustles.com+bug-reports:        https://github.com/scrapertweeter3-prog/side-hustle-hourly-hs/issues+copyright:          2026 Poket Dev LLC+category:           Math+build-type:         Simple+extra-doc-files:    README.md+                  , CHANGELOG.md++source-repository head+  type:     git+  location: https://github.com/scrapertweeter3-prog/side-hustle-hourly-hs++library+  exposed-modules:  SideHustle.Hourly+  hs-source-dirs:   src+  build-depends:    base >=4 && <5+  default-language: Haskell2010+  ghc-options:      -Wall
+ src/SideHustle/Hourly.hs view
@@ -0,0 +1,31 @@+-- | True hourly rate math for side hustles and gig work.+--+-- A gig's posted rate is gross cash over paid hours. The real one comes+-- off the gross in platform fees and job costs first, then divides by+-- hours that include the unpaid admin around the paid ones: messaging+-- clients, invoicing, restocking, the drive back from the job. This+-- module computes that rate and compares two gigs on it.+module SideHustle.Hourly+  ( netCash+  , hourlyRate+  , compareGigs+  ) where++-- | Net cash a gig leaves after the platform cut and the costs of+-- doing the job. A cut of 0.15 means the platform keeps 15 percent.+netCash :: Double -> Double -> Double -> Double+netCash gross platformCut costs = gross * (1 - platformCut) - costs++-- | Net cash over total hours, paid and unpaid. Returns 0 when there+-- are no hours at all.+hourlyRate :: Double -> Double -> Double -> Double+hourlyRate net paidHours unpaidHours+  | paidHours + unpaidHours <= 0 = 0+  | otherwise                    = net / (paidHours + unpaidHours)++-- | The better of two hourly rates and the per-hour gap between them,+-- returned as (better rate, how far ahead it is).+compareGigs :: Double -> Double -> (Double, Double)+compareGigs rateA rateB+  | rateA >= rateB = (rateA, rateA - rateB)+  | otherwise      = (rateB, rateB - rateA)