Giter VIP home page Giter VIP logo

skala's Introduction

Skala

Build Status Build Status Download

Codacy Badge Coverage Status

Build Status

Utilities for Scala

skala.math

skala.math.BigInts

sqrt()

The square root of a BigInt value

import io.kevinlee.skala.math.BigInts._

sqrt(BigInt(9))
// Result: BigDecimal(3)

sqrt(BigInt(10))
// Result: BigDecimal(3.162277660168379331998893544432718)


sqrt(BigInt(-1))
// Result: IllegalArgumentException

findSqrt()

It returns Option may or may not have a square root of a BigInt value. This method doesn't throw any exception when a negative number is passed as a parameter. Instead, it returns None.

import io.kevinlee.skala.math.BigInts._

findSqrt(BigInt(9))
// Result: Some(BigDecimal(3))

findSqrt(BigInt(10))
// Result: Some(BigDecimal(3.162277660168379331998893544432718))


findSqrt(BigInt(-1))
// Result: None

mean()

It calculates a mean of TraversableLike[BigInt, TraversableLike[BigInt, _]].

import io.kevinlee.skala.math.BigInts._

val numbers = List[BigInt](1, 2, 3)
mean(numbers)  // returns BigDecimal(2)

median()

It finds a median of Seq[BigInt].

import io.kevinlee.skala.math.BigInts._

val numbers = List[BigInt](1, 2, 3, 4)
median(numbers)  // return BigDecimal(2.5)
import io.kevinlee.skala.math.BigInts._

val numbers = List[BigInt](2, 4, 3, 1)
median(numbers)  // return BigDecimal(2.5)
import io.kevinlee.skala.math.BigInts._

val numbers = List[BigInt](1, 2, 3, 4, 5)
median(numbers)  // return BigDecimal(3)
import io.kevinlee.skala.math.BigInts._

val numbers = List[BigInt](2, 3, 5, 4, 1)
median(numbers)  // return BigDecimal(3)

skala.math.BigDecimals

sqrt()

The square root of a BigDecimal value

import io.kevinlee.skala.math.BigDecimals._

sqrt(BigDecimal(9))
// Result: BigDecimal(3)

sqrt(BigDecimal(10))
// Result: BigDecimal(3.162277660168379331998893544432718)

sqrt(BigDecimal(-1))
// Result: IllegalArgumentException

findSqrt()

It returns Option may or may not have a square root of a BigDecimal value. This method doesn't throw any exception when a negative number is passed as a parameter. Instead, it returns None.

import io.kevinlee.skala.math.BigDecimals._

findSqrt(BigDecimal(9))
// Result: Some(BigDecimal(3))

findSqrt(BigDecimal(10))
// Result: Some(BigDecimal(3.162277660168379331998893544432718))


findSqrt(BigDecimal(-1))
// Result: None

mean()

It calculates a mean of TraversableLike[BigDecimal, TraversableLike[BigDecimal, _]].

import io.kevinlee.skala.math.BigDecimals._

val numbers = List[BigDecimal](1, 2, 3)
mean(numbers)  // returns BigDecimal(2)

median()

It finds a median of Seq[BigDecimal].

import io.kevinlee.skala.math.BigDecimals._

val numbers = List[BigDecimal](1, 2, 3, 4)
median(numbers)  // return BigDecimal(2.5)
import io.kevinlee.skala.math.BigDecimals._

val numbers = List[BigDecimal](2, 4, 3, 1)
median(numbers)  // return BigDecimal(2.5)
import io.kevinlee.skala.math.BigDecimals._

val numbers = List[BigDecimal](1, 2, 3, 4, 5)
median(numbers)  // return BigDecimal(3)
import io.kevinlee.skala.math.BigDecimals._

val numbers = List[BigDecimal](2, 3, 5, 4, 1)
median(numbers)  // return BigDecimal(3)

Try with Resource

tryWith

import io.kevinlee.skala.util.SideEffect.tryWith
tryWith(AutoCloseable) { autoCloseable =>
  // run block
}

tryWith is similar to Java's Try with Resource so it may throw an exception if the block or AutoCloseable throws any exception.

val result: WhatEverTheRunBlockReturns = tryWith(AutoCloseable) { autoCloseable =>
  // run block
}
tryWith(new FileInputStream("/path/to/file.txt")) { inputStream =>
  var c = inputStream.read()
  while (c != -1) {
    print(c.asInstanceOf[Char])
    c = inputStream.read()
  }
}
tryWith(new FileInputStream("/path/to/file.txt")) { inputStream =>
  tryWith(new InputStreamReader(inputStream)) { reader =>
    var c = reader.read()
    while (c != -1) {
      print(c.asInstanceOf[Char])
      c = reader.read()
    }
  }
}
val result = tryWith(new SomeResource()) { someSource =>
  someSource.get
}

Get Skala

In your build.sbt, add the following repo and dependency.

Note: It supports Scala 2.11 and 2.12.

resolvers += "3rd Party Repo" at "http://dl.bintray.com/kevinlee/maven"

libraryDependencies += "io.kevinlee" %% "skala" % "0.2.0"

skala's People

Contributors

kevin-lee avatar

Stargazers

Kevin Ko avatar Seol Dong Min avatar Hyunjin CHA avatar namkung hyeon avatar Whosoon Sean Hwang avatar itnote avatar Woojin.joe avatar Alejandro Vidal Castillo avatar

Watchers

James Cloos avatar Woojin.joe avatar  avatar  avatar  avatar

skala's Issues

String utility with uncapitalize

String utility with uncapitalize

There should be a utility method called uncapitalize to uncapitalize a String value.

e.g.)

"Test".uncapitalize
// "test"

"TestSomething".uncapitalize
// "testSomething"

"".uncapitalize
// ""

val a: String = null
a.uncapitalize
// java.lang.NullPointerException

tryWith should work the same as Java's try-with-resources and remove TryWith

Issue

Summary

tryWith should work the same as Java's try-with-resources.

Project Details

Version: 0.1.0

Description

The current tryWith just ignores any Throwable thrown when closing the resource. Java's try-with-resources does not ignore it. What it does is

  • When an exception (Throwable), let's call it ex1, is thrown inside try,

    • If close does not throw any exception, it throws the ex1
    • If close throws another exception (ex2), it adds ex2 to ex1 as its suppressed throwable then throws the ex1 (ex1.addSuppressed(ex2); throw ex1)
  • When no exception is thrown inside try,

    • If close does not throw any exception, nothing happens and the result is returned
    • If close throws an exception (ex), it throws the ex

TryWith does not work well with this idea and there might be several issues with it so it has to be removed.

So what are issues?
What happens when

  1. Try is Success but close is throwing not NonFatal, what should it do?
    • throws it?
    • or return a new Failure with some fatal throwable (doesn't make sense)?
  2. Try is Failure and close is throwing not NonFatal, what should it do?
    • throws the fatal one (different from try-with-resources)?
    • or return the Failure from Try after adding the fatal throwable from close to the NonFatal(ex) in the Failure using Throwable#addSuppressed, (does it make sense?)?

Solution

Make tryWith the same as Java's try-with-resources by adding suppressed one from closing if it's thrown. By doing this, any Throwable thrown inside finally when closing can be kept in the original Throwable so that it can remove logging which makes this method so ugly with the implicit parameter.


TryWith should be removed and let the users decide what to do with tryWith.
If it's necessary to have Try having the same behavior as try-with-resources's, it should be done in such a way that tryWith is wrapped in Try.
e.g.)

Try(tryWith(new Resource()) { resource =>
  // do something.
})

BigInts.Sqrt and BigDecimals.Sqrt for negative numbers

In Java, java.lang.Math.sqrt(negative double) is always Double.NaN. BigInt and BigDecimal in Scala or (BigInteger and BigDecimal in Java), however, don't have NaN. So BigInts.sqrt() and BigDecimals.sqrt() can't simply return NaN nor can these have instances for NaN because

  1. Double.NaN in Java is 0.0d / 0.0 which means ArithmeticException: Division undefined when the same calculation is done on BigDecimal (e.g. BigDecimal(0.0D) / BigDecimal(0.0) => java.lang.ArithmeticException: Division undefined).
  2. BigInt and BigDecimal in Scala are final class so it can't be sub-classed to create NaN.

So a possible solution to handle this problem is

  1. to make sure that the input value is a non-negative number.
    • If not, throw an exception.
  2. add another method that returns Option type.
    • so that it can return None for non-negative numbers.

toOrdinal

It would be convenient to have methods converting integers (Int, Long and BigInt) into ordinal number String.

e.g.)

val number = 1
println(toOrdinal(number))
1st

Update libs and plugins

Update libs and plugins.

libraryDependencies ++= List(
  "org.scalatest" % "scalatest_2.11" % "2.2.6" % "test",
  "com.storm-enroute" %% "scalameter" % "0.7",
  "org.scalamock" %% "scalamock-scalatest-support" % "3.2.2" % "test"
)

Due to this, the following plugin upgrade has been dropped.

addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.3.5")

addSbtPlugin("org.scoverage" % "sbt-coveralls" % "1.1.0")

tryWith should handle an error properly using an external handler when close fails

Description

tryWith should handle an error properly using an external handler when the close method in the given AutoCloseable throws an exception.

For example, it can be an external logger like

implicit val logger: Throwable => Unit = ex => logger.debug(s"some message $ex")

tryWith(new InputStreamReader(inputStream)) { reader =>
  // doSomething
}

or

tryWith(new InputStreamReader(inputStream)) { reader =>
  // doSomething
} (ex => logger.debug(s"some message $ex"))

Why

An exception thrown when closing the given resource should be handled properly or logged for debugging.

Add try with resource

Similar to Java's Try with Resources, there should an easy way to use AutoCloseable in Scala.

  • Java
try (final InputStream inputStream = new FileInputStream("/path/to/file.txt")) {
  int c = inputStream.read();
  while (c != -1) {
    System.out.print((char) c);
    c = inputStream.read();
  }
}
  • Scala
tryWith(new FileInputStream("/path/to/file.txt")) { inputStream =>
  var c = inputStream.read()
  while (c != -1) {
    print(c.asInstanceOf[Char])
    c = inputStream.read()
  }
}

  • Java
try (final InputStream inputStream = new FileInputStream("/path/to/file.txt");
     final Reader reader = new InputStreamReader(inputStream)) {
  int c = reader.read();
  while (c != -1) {
    System.out.print((char) c);
    c = reader.read();
  }
}
  • Scala
tryWith(new FileInputStream("/path/to/file.txt")) { inputStream =>
  tryWith(new InputStreamReader(inputStream)) { reader =>

    var c = reader.read()
    while (c != -1) {
      print(c.asInstanceOf[Char])
      c = reader.read()
    }
  }
}

PathString to merge path String

PathString should merge the given two String then create a / delimited String.

e.g.)

/ for XNix

val a = "something"
val b = "sub"
val c = a / b   // result: "something/sub"
val c = "a"/"b"/"c"   // result: "a/b/c"
val c = "a" / "b" / "c"   // result: "a/b/c"
val c = "a/" / "/b" / "/c/" / "d"   // result: "a/b/c/d"

\ For Windows

val a = "something"
val b = "sub"
val c = a \ b   // result: "something\sub"
val c = "a"\"b"\"c"   // result: "a\b\c"
val c = "a" \ "b" \ "c"   // result: "a\b\c"
val c = "a\\" \ "\\b" \ "\\c\\" \ "d"   // result: "a\b\c\d"

Project compilation fails due to unresolved dependency (xml-apis)

Problem

The skala project compilation fails due to unresolved dependency that xml-apis#xml-apis;1.3.04.

The detailed error messages are

> update
[info] Updating {file:/path/to/skala/}skala...
[info] Resolving org.scala-lang.modules#scala-parser-combinators_2.11;1.0.1[info] Resolving org.scala-lang.modules#scala-parser-combinators_2.11;1.0.4[info] Resolving jline#jline;2.12.1 ...
[warn] 	::::::::::::::::::::::::::::::::::::::::::::::
[warn] 	::          UNRESOLVED DEPENDENCIES         ::
[warn] 	::::::::::::::::::::::::::::::::::::::::::::::
[warn] 	:: xml-apis#xml-apis;1.3.04: configuration not found in xml-apis#xml-apis;1.3.04: 'master(compile)'. Missing configuration: 'compile'. It was required from org.jfree#jfreechart;1.0.17 compile
[warn] 	::::::::::::::::::::::::::::::::::::::::::::::
[warn]
[warn] 	Note: Unresolved dependencies path:
[warn] 		xml-apis:xml-apis:1.3.04
[warn] 		  +- org.jfree:jfreechart:1.0.17
[warn] 		  +- com.github.wookietreiber:scala-chart_2.11:0.4.2
[warn] 		  +- com.storm-enroute:scalameter_2.11:0.6 (/path/to/skala/build.sbt#L26-37)
[warn] 		  +- io.kevinlee:skala_2.11:0.0.6
[trace] Stack trace suppressed: run last *:update for the full output.
[error] (*:update) sbt.ResolveException: unresolved dependency: xml-apis#xml-apis;1.3.04: configuration not found in xml-apis#xml-apis;1.3.04: 'master(compile)'. Missing configuration: 'compile'. It was required from org.jfree#jfreechart;1.0.17 compile
[error] Total time: 0 s, completed 26/03/2017 12:16:09 AM

Cause

That is caused by one of the dependency libraries that is scalameter. It seems like the scalameter uses xml-apis and it's unresolved somehow.

Possible Solution

Upgrade scalameter to the version that doesn't have the dependency issue.

There was another problem though. The scope of the scalameter is not Test but Compile. This library is used in test only so it has to have Test scope. Please fix it when fixing scalameter dependency issue.

  • Todo:
    • Change the scope to Test
    • Upgrade scalameter
    • Make sure it doesn't have any error anymore.

Cross build for Scala 2.11 and 2.12

Issue

Cross build for Scala 2.11 and 2.12

Project Details

Version: 0.0.8

Description

Since both 2.11 and 2.12 are commonly used, it is required to build Skala for both 2.11 and 2.12

Cause

Support for Scala 2.11 and 2.12 is required.

Solution

Set crossScalaVersions in build.sbt.

e.g.)

crossScalaVersions := Seq("2.11.12", "2.12.4")

Known Issues and TODO

There are some issues found while working on this issue.

  • Libraries are too old to support 2.12 => library version up required.
  • Some plugin versions are too old => plugin version up required (This might be optional but it's better to do now).
  • Test code using ScalaMock is broken for Scala 2.12 => Separate tests for 2.11 and 2.12 required.
  • Build scripts have to be updated with cross-build options (e.g. +publish +test +package, etc.)

tryWith should evaluate the parameter once

Problem

If an expression passed to tryWith is an instantiation of some type which may create a new resource, it might be removed after tryWith ends.

e.g.) Using scala-csv

  val oldFile = new File("/path/to/old-file.csv")
  val newFile = new File("/path/to/new-file.csv")

  tryWith(CSVReader.open(oldFile)) { oldCsv =>
    tryWith(CSVWriter.open(newFile)) { newCsv =>
      val all = oldCsv.toStream
      newCsv.writeAll(all)
    }
  }

The end result that is /path/to/new-file.csv is empty (0 byte).

Possible Causes

It happens when the parameter of tryWith is an instantiation of a resource like

tryWith(CSVWriter.open(newFile)) {
}

but not

val writer = CSVWriter.open(newFile)
tryWith(writer) {
}

So it looks like the parameter is evaluated (instantiation) more than once.

Possible Solutions

The source code of tryWith is

  def tryWith[T <: AutoCloseable, R](closeable: => T)(f: T => R): R = {
    try {
      f(closeable) // <= the first instantiation of closeable
    } finally {
      if (closeable != null) { // <= the second instantiation of closeable
        closeable.close()  // // <= the third instantiation of closeable
      }
    }
  }

It means the second one removes and re-create the resource and the third one can remove and re-create the second one. So assigning the resource to a val can solve it.

    val resource = closeable
    // then use resource instead of closeable
    try {
      f(resource)
    } finally {
      if (resource != null) {
        resource.close()
      }
    }

Upgrade sbt to 1.x

Issue

Summary

Upgrade sbt to 1.x.x from 0.13.x.

Project Details

Version: 0.0.10

Description

More and more sbt plugins are released for sbt 1.x and some of them do not support 0.13 anymore. So it is good to upgrade sbt to 1.x.

Solution

Upgrade sbt to the latest 1.x and also upgrade the plugins if required.

mode doesn't work for multiple mode values

Current mode methods do not work correctly if there are more than one mode value.

e.g.)

val result = BigInts.mode(List[BigInt](1, 1, 2, 3, 3, 3, 3, 5, 5, 7, 7, 7, 7, 100, 101, 101, 101, 101, 8))

The result should be

List[BigInt](3, 7, 101)

This bug was found while I was working on #4.

Add typesafe equality check (i.e. === and !===)

Issue

Summary

Scala's equality checks (i.e == and !=) are not typesafe.

Project Details

Version: 0.0.9

Description

Scala's equality check is the same as Java. It doesn't check the type in compile-time.
So code like 999 == "999" is valid in Scala although it can never be true as 999 and "999" are different types.
It can be checked in compile-time and prevent from writing meaningless equality check which is also most likely a bug in the code.

Solution

Add === and !== which allow only the same type for equality check. There are libraries having === and !== yet it might be too much to use those libraries to have just better equality check. Since Skala is supposed to be a small library, it's good to have them here.

Once done, Skala itself should use them for better code quality.

tryWith should return Try[T] instead of T

tryWith should return Try instead of return a result or throwing an exception.

The current tryWith returns the direct result or throws an exception.

// result is what resource.doSomething() returns
// or if anything goes wrong, it may throw an exception.
val result = tryWith(someCloseable) { resource =>
  resource.doSomething()
}

It needs to use Try instead of dealing directly with an exception or the result.

// result is either Success[T] where T is the type of the value resource.doSomething() returns
// or Failure containing an exception (Throwable) if the exception was thrown.
val result = tryWith(someCloseable) { resource =>
  resource.doSomething()
}

tryWith returning Try[T] does not work well with nested tryWiths

Problem

tryWith returning Try[T] does not work well with nested tryWiths.

It has something to do with issue #18.

tryWith returning Try[T] can handle a single tryWith case well just like

val result = tryWith(someCloseable) { resource =>
  resource.doSomething()
}
// result might be Success(value) where the value is what resource.doSomething() returns.

However, the following code returns Try[Try[T]].

val result = tryWith(resource) { someResource =>
  tryWith(anotherResource) { resource =>
    resource.doSomething()
  }
}
// result might be Success(Success(value)) not Success(value)
// again, the value is what resource.doSomething() returns.

Cause

tryWith returns Try[T] so the nested one also returns Try[T] and that's why it eventually gives Try[Try[T]].

Possible Solution

It should be another tryWith handling nested tryWiths.

TryWith should work like tryWith but it should return Try type

TryWith should work like tryWith but it should return Try type. There is already tryWith to close resources after using but it's also good to have TryWith that returns Try type after using and closing its resource.

e.g.)

val result: Try[Int] = TryWith(new SomeResource()) { resource =>
  resource.calculate() // the calculate() method returns Int
}

In the example above, if resource.calculate() throws an exception TryWith returns Failure with the exception thrown. Otherwise it returns Success having the result returned from resource.calculate().

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.