Last active
August 28, 2021 10:13
-
-
Save stantonk/6773672 to your computer and use it in GitHub Desktop.
Scala for Python Programmers, examples
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Notes: | |
Despite Scala's appearances, it is, in fact, a Statically Typed language. | |
It has just eliminated a great deal of the "type vomit" people are used | |
to seeing in Statically Typed languages (e.g. C, C++, Java). It often | |
can infer the type on its own. It also combines functional and | |
object-oriented programming paradigms in a fashion that feels similar | |
to Python. | |
*/ | |
/* | |
Python lists | |
l = ["one", "two", "three"] | |
print l[0] | |
for a in l: | |
print a | |
*/ | |
// scala Lists | |
val l = List("one", "two", "three") | |
println(l(0)) // note how scala uses parens instead of brackets for array indexing | |
for (a <- l) | |
println(a) | |
/////////////////////////////////////////////////////////////////////////////////////// | |
/////////////////////////////////////////////////////////////////////////////////////// | |
// Python dict | |
>>> x = {"dog": "Woof", "cat": "Meow"} | |
>>> for k, v in x.items(): | |
... print "%s=%s" % (k, v) | |
... | |
dog=Woof | |
cat=Meow | |
>>> print "the dog says " + x["dog"] + " and the cat says " + x["cat"] | |
the dog says Woof and the cat says Meow | |
>>> print x.get("duck", "quack") | |
quack | |
>>> x['fox'] = '??????' | |
>>> print "what the fox say: " + x['fox'] | |
what the fox say: ?????? | |
// Scala Maps | |
scala> var x = Map("dog" -> "Woof", "cat" -> "Meow") | |
x: scala.collection.immutable.Map[String,String] = Map(dog -> Woof, cat -> Meow) | |
scala> println("the dog says " + x("dog") + "and the cat says " + x("cat")) // like lists, note parens..not brackets | |
the dog says Woofand the cat says Meow | |
scala> for ((k, v) <- x) | |
| printf("%s=%s\n", k, v) | |
dog=Woof | |
cat=Meow | |
scala> println(x.getOrElse("duck", "quack")) | |
quack | |
scala> x += ("fox" -> "??????") | |
scala> println("what the fox say: " + x("fox")) | |
what the fox say: ?????? | |
/////////////////////////////////////////////////////////////////////////////////////// | |
/////////////////////////////////////////////////////////////////////////////////////// | |
/* | |
Python lambda | |
greeting = lambda name: "Hello " + name | |
print greeting("Kevin") | |
*/ | |
// scala function literal | |
val greeting = (name: String) => "Hello " + name | |
println(greeting("Kevin")) | |
/////////////////////////////////////////////////////////////////////////////////////// | |
/* | |
Python function (brief) | |
def max2(x, y): return x if x > y else y | |
>>> max2(17, 19) | |
19 | |
>>> max2(19, 17) | |
19 | |
*/ | |
// scala, function definition (brief) | |
def max2(x: Int, y: Int) = if (x > y) x else y | |
max2: (x: Int, y: Int)Int | |
scala> max2(17, 19) | |
res2: Int = 19 | |
scala> max2(19, 17) | |
res3: Int = 19 | |
/////////////////////////////////////////////////////////////////////////////////////// | |
/* | |
Python, a regular function | |
def max(x, y): | |
if x > y: | |
return x | |
else: | |
return y | |
*/ | |
// scala, a regular function (most formal definition) | |
def max(x: Int, y: Int): Int = { | |
if (x > y) x | |
else y | |
} | |
// scala can usually infer the return type, so you can leave it off | |
// in some cases it can't though (i.e. recursion) | |
def max(x: Int, y: Int) = { | |
if (x > y) x | |
else y | |
} | |
/////////////////////////////////////////////////////////////////////////////////////// | |
/* | |
Python, for loop over range of numbers | |
# note, last number printed is 4 | |
for i in range(0, 5): | |
print i | |
*/ | |
// scala is inclusive over the range while Python is not | |
// last number printed is 5 | |
for (i <- 0 to 5) | |
println(i) | |
// interesting to note, this code is equivalent: | |
for (i <- 0.to(5)) | |
println(i) | |
// because "to" is actually not an operator, but a method on Int, see: | |
scala> 0.to(5) | |
res16: scala.collection.immutable.Range.Inclusive = Range(0, 1, 2, 3, 4, 5) | |
scala> 0 to 5 | |
res17: scala.collection.immutable.Range.Inclusive = Range(0, 1, 2, 3, 4, 5) | |
// this may seem somewhat odd, but it actually is similar (at least to my non-expert eye) | |
// to how operators are implemented in languages like Python and PHP, e.g. | |
// python | |
>>> x = 5 | |
>>> x.__add__ | |
<method-wrapper '__add__' of int object at 0x7fc339c10788> | |
>>> x.__add__(2) | |
7 | |
>>> x + 2 | |
7 | |
// scala | |
scala> val x = 5 | |
x: Int = 5 | |
scala> x.+(2) | |
res20: Int = 7 | |
scala> x + 2 | |
res21: Int = 7 | |
/////////////////////////////////////////////////////////////////////////////////////// | |
/* | |
Python concatenating lists | |
list1 = [1, 2] | |
list2 = [3, 4] | |
biglist = list1 + list2 | |
*/ | |
// scala concatenating lists | |
val list1 = List(1, 2) | |
val list2 = List(3, 4) | |
val biglist = list1 ::: list2 | |
// NOTE: In Scala, Lists are immutable. Python's lists, however, are mutable. If you want | |
// mutability, use Scala's Array. | |
// scala, prepend an element (using the "cons" operator, ::) to an existing | |
// list will generate a new list: | |
val list1 = List(2, 3) | |
val newlist = 1 :: list1 | |
// in python, you would do this using concatenation and a temporary list of length 1 | |
list1 = [2, 3] | |
newlist = [1] + list1 | |
// or you could prepend the 1 to the existing list at the front, but this would be | |
// inefficient | |
list1.insert(0, 1) | |
/////////////////////////////////////// | |
// DATA TYPES | |
////////////////////////////////////// | |
/// Tuples /// | |
// Python tuples | |
>>> pair = (1, "foo") | |
>>> print pair[0] | |
1 | |
>>> print pair[1] | |
foo | |
// Scala has tuples too (yay, no JavaBean silliness for returning multiple | |
// values of varied types!) | |
// Both Scala and Python tuples are immutable, but Scala's are typesafe, | |
// hence the strange accessing mechanism (pair._1 vs. pair[0]). | |
scala> val pair = (1, "foo") | |
pair: (Int, String) = (1,foo) | |
scala> println(pair._1) | |
1 | |
scala> println(pair._2) | |
foo | |
/// Sets /// | |
// Python | |
>>> basket1 = set(["apple", "pear"]) | |
>>> basket1.add("strawberry") | |
>>> basket2 = set(["grape", "apple", "starfruit"]) | |
>>> print "common to both: %s" % (basket1 & basket2) | |
common to both: set(['apple']) | |
>>> print "in either basket: %s" % (basket1 | basket2) | |
in either basket: set(['strawberry', 'grape', 'apple', 'pear', 'starfruit']) | |
// Scala | |
scala> var basket1 = Set("apple", "pear") | |
basket1: scala.collection.immutable.Set[String] = Set(apple, pear) | |
scala> basket1 += "strawberry" | |
scala> var basket2 = Set("grape", "apple", "starfruit") | |
basket2: scala.collection.immutable.Set[String] = Set(grape, apple, starfruit) | |
scala> println("common to both: " + (basket1 & basket2)) | |
common to both: Set(apple) | |
scala> println("in either basket: " + (basket1 | basket2)) | |
in either basket: Set(grape, apple, pear, strawberry, starfruit) | |
// but if you needed a mutable set: | |
import scala.collection.mutable | |
val mutableSet = mutable.Set("a", "b") | |
mutableSet += "c" | |
// or maybe an immutable HashSet? | |
import scala.collection.immutable.HashSet | |
var hashSet = HashSet(1, 2, 3) | |
/////////////////////////////////////// | |
// FILE I/O BASICS | |
////////////////////////////////////// | |
// Python | |
import sys | |
if len(sys.argv) > 0: | |
for line in open(sys.argv[1]): | |
print line.rstrip('\r\n') # scala.io.Source removes line terminators | |
else: | |
sys.stderr.write('Please enter filename') | |
// Scala | |
import scala.io.Source | |
if (args.length > 0) { | |
for (line <- Source.fromFile(args(0)).getLines) | |
println(line) | |
} else { | |
Console.err.println("Please enter filename") | |
} | |
/////////////////////////////////////// | |
// Classes and Objects | |
////////////////////////////////////// | |
// Python | |
class Dog(object): | |
def __init__(self, name): | |
self.name = name | |
def speak(self): | |
print '%s: Bark!' % self.name | |
def command(self, cmd): | |
print '%s ::%s::' % (self.name, cmd) | |
dog = Dog('Rover') | |
dog.speak() | |
// Scala | |
class Dog(name: String) { | |
println("This line runs upon instantiation of a Dog, it is the primary constructor") | |
def speak() { println(name + ": Bark!") } | |
def command(cmd: String) = { println(name + " ::" + cmd + "::") } | |
} | |
val dog = new Dog("Rover") | |
dog.speak() | |
dog.command("sit") | |
//////////////////// | |
//////////////////// | |
Raw strings """ """ | |
Unicode \u0041 | |
//// TODO //// | |
// other control structures (while,...) | |
// exceptions | |
// objects | |
// classes | |
// example of using builtin java libraries directly in scala | |
// example of using 3rd party java libraries directly in scala | |
// sbt | |
// maven integration | |
// dependencies, builds, etc. |
Hi!
Thank you very much for this gist. As a python developer trying to learn Scala, this is very useful!
I was trying to use this example and found out syntax in line 300 is deprecated.
I tried def speak() : Unit = {println(name + ": Bark!") }
and worked with no warnings. It's not a judgement! I am just trying to help improve this gist which helped me a lot :)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Of course I search for Python to Scala and find you @stantonk