Skip to content

Instantly share code, notes, and snippets.

@alopatindev
Last active December 25, 2016 21:24
Show Gist options
  • Save alopatindev/9fa774c7a375b1772083fc976f6ce168 to your computer and use it in GitHub Desktop.
Save alopatindev/9fa774c7a375b1772083fc976f6ce168 to your computer and use it in GitHub Desktop.
Domain selection tool based on interest in technologies the domain relates to
// Developed by Alexander Lopatin (https://alopatindev.github.io)
// See https://alopatindev.github.io/2016/04/30/career-shift-time/
// This program is licensed under the terms of WTFPL
object JobsSelector extends App {
import scala.language.postfixOps
import scala.util.Try
val backendTechs: Set[String] = Set("nodejs", "Scala", "C++", "C", "MySQL", "PostgreSQL", "MongoDB", "Redis", "OrientDB", "Databases", "Play Framework", "JavaScript", "GNU/Linux", "Free Software", "Java", "nginx", "Network Stack", "JVM")
val frontendTechs: Set[String] = Set("JavaScript", "HTML5", "CSS", "UI", "UX", "WebGL", "Vim", "Free Software", "GNU/Linux")
val fullstackTechs: Set[String] = backendTechs ++ frontendTechs
// domain -> techs
val domains: Map[String, (Set[String], Double)] = Map(
"GameDev (Mobile)" -> (Set("Windows", "OSX", "VS", "Vim", "Java", "C++", "C#", "Objective-C/Swift", "Python", "bash", "bat", "iOS", "Android", "JNI", "Perforce", "svn", "git", "GLSL and Vulkan", "UI", "JVM", "Unity3D", "Marmalade", "Multithreading", "Network Client", "Proprietary Software", "Machine Learning", "Other NP problems"), 0.1),
"GameDev (Desktop)" -> (Set("Windows", /*"GNU/Linux",*/ "OSX", "VS", "Vim", "C++", "C#", "Objective-C/Swift", "Python", "bash", "bat", "Perforce", "svn", "git", "GLSL and Vulkan", "HLSL", "UI", ".net", "Unreal", "Multithreading", "Network Client", "Proprietary Software", "Machine Learning", "Other NP problems"), 0.1),
"Finance / Bank" -> (Set("Scala", "Java", "JavaEE", "OracleDB", "Math: Statistics", "Math: Probability Theory", "Economy", "Functional Programming", "Imperative OOP", "GNU/Linux", "Vim", "IDEA", "Eclipse", "git", "Multithreading", "Distributed Computations", "Reactive Programming", "Proprietary Software", "Test Automation", "ssh", "Tomcat", "Network Stack"), 0.1),
"Data Science" -> (Set("MatLab/Mathcad/Mathematica", "Math: Calculus", "Math: Discrete", "Math: Probability Theory", "Math: Statistics", "Databases", "NoSQL", "MongoDB", "PostgreSQL", "MySQL", "Python", "Functional Programming", "Haskell", "Vim", "LaTeX", "GNU/Linux", "git", "Distributed Computations", "Multithreading", "CUDA", "OpenCL", "Machine Learning", "Other NP problems", "Proprietary Software", "Test Automation"), 0.1),
"Android Dev" -> (Set("GNU/Linux", "IDEA", "Eclipse", "Vim", "git", "Java", "Scala", /* "Kotlin", */ "JNI", "C++", "UI", "UX", "GLSL and Vulkan", "Network Client", "Proprietary Software", "Test Automation"), 0.6),
"Embedded" -> (Set("C", "ASM", "Electronics", "Windows", "Vim", "Proprietary Software", "Network Stack", "Device Drivers"), 0.3),
"Linux Kernel Dev" -> (Set("C", "ASM", "Computer Design", "Vim", "GNU/Linux", "bash", "Free Software", "Reverse Enigneering", "Multithreading", "Network Stack", "Device Drivers"), 0.6),
"GNU/Linux Distro Dev" -> (Set("Free Software", "GNU/Linux", "Vim", "C", "C++", "Python", "bash", "git", "ssh", "Test Automation"), 0.7),
"Enterprise" -> (Set("JavaEE", "OracleDB", "Proprietary Software", "Windows", "Distributed Computations", "Multithreading", "Reactive Programming", "IDEA", "Eclipse", "Test Automation", "ssh", "GNU/Linux", "Network Stack", "Tomcat"), 0.0),
"Desktop Apps" -> (Set("C++", "Qt", "C#", ".net", "Java", "JVM", "CUDA", "GLSL and Vulkan", "Multithreading", "Distributed Computations", "Network Client", "bat", "bash", "Proprietary Software", "Test Automation", "Windows", "GNU/Linux", "OSX"), 0.7),
"QA Engineer (Backend)" -> ((Set("Test Automation") ++ backendTechs), 0.1),
//"Tech Writer" -> (Set(), 0.0),
//"Tools Developer" -> (Set(), 0.0),
//"System Admin (POSIX)" -> (Set("GNU/Linux", "bash", "Network"), 0.0),
//"DevOps" -> (Set("ssh", "nginx", "People Management"), 0.0),
//"Build Engineer" -> (Set(), 0.0),
//"People Management" -> (Set() 0.0),
//"Consult / Instructor" -> (Set(), 0.0),
"Backend" -> (backendTechs, 1.0),
"Frontend" -> (frontendTechs, 0.5),
"Fullstack" -> (fullstackTechs, 0.5)
)
// tech -> (interest, knowledge, xp)
val technologies: Map[String, (Double, Double, Double)] = Map(
"Free Software" -> (1.0, 1.0, 1.0),
"Proprietary Software" -> (0.0, 0.5, 0.5),
"Windows" -> (0.0, 0.5, 0.5),
"GNU/Linux" -> (1.0, 1.0, 1.0),
"OSX" -> (0.0, 0.3, 0.4),
"Android" -> (0.5, 0.5, 0.8),
"iOS" -> (0.0, 0.3, 0.5),
"VS" -> (0.0, 0.2, 0.7),
"Vim" -> (1.0, 0.5, 1.0),
"Eclipse" -> (0.0, 0.0, 0.0),
"IDEA" -> (0.5, 0.0, 0.0),
"C" -> (1.0, 0.8, 0.8),
"C++" -> (0.0, 0.7, 1.0),
"Objective-C/Swift" -> (0.0, 0.6, 0.5),
"Haskell" -> (1.0, 0.1, 0.0),
"Rust" -> (0.7, 0.1, 0.0),
"Java" -> (0.1, 0.5, 0.5),
"JavaEE" -> (0.0, 0.0, 0.0),
"Scala" -> (1.0, 0.5, 0.1),
"Kotlin" -> (1.0, 0.0, 0.0),
"C#" -> (0.0, 0.0, 0.1),
"Python" -> (0.0, 0.8, 0.5),
"Databases" -> (0.5, 0.3, 0.4),
"NoSQL" -> (1.0, 0.1, 0.0),
"MySQL" -> (0.0, 0.1, 0.0),
"PostgreSQL" -> (1.0, 0.0, 0.0),
"MongoDB" -> (1.0, 0.0, 0.0),
"Redis" -> (1.0, 0.0, 0.0),
"OrientDB" -> (1.0, 0.0, 0.0),
"OracleDB" -> (0.0, 0.0, 0.0),
"Imperative OOP" -> (0.1, 0.5, 0.8),
"Functional Programming" -> (1.0, 0.5, 0.1),
"Reactive Programming" -> (1.0, 0.5, 0.1),
"Multithreading" -> (1.0, 0.8, 0.8),
"Distributed Computations" -> (1.0, 0.2, 0.0),
"OpenCL" -> (0.5, 0.0, 0.0),
"CUDA" -> (0.0, 0.0, 0.0),
"MatLab/Mathcad/Mathematica"->(0.5, 0.0, 0.0),
"Machine Learning" -> (0.5, 0.0, 0.0),
"Neural Networks" -> (0.5, 0.0, 0.0),
"Other NP problems" -> (0.5, 0.0, 0.0),
"git" -> (1.0, 0.2, 0.5),
"Perforce" -> (0.0, 0.5, 0.2),
"svn" -> (0.0, 0.8, 0.5),
"GLSL and Vulkan" -> (0.5, 0.2, 0.2),
"HLSL" -> (0.0, 0.0, 0.1),
"Math: Calculus" -> (0.0, 0.5, 0.0),
"Math: Discrete" -> (0.5, 0.5, 0.0),
"Math: Probability Theory" -> (0.5, 0.0, 0.0),
"Math: Statistics" -> (0.5, 0.0, 0.0),
"bash" -> (1.0, 1.0, 1.0),
"bat" -> (0.0, 0.5, 0.5),
"nodejs" -> (0.0, 0.0, 0.0),
"JavaScript" -> (0.5, 0.0, 0.0),
"HTML5" -> (0.2, 0.0, 0.0),
"CSS" -> (0.1, 0.1, 0.0),
"Play Framework" -> (0.5, 0.0, 0.0),
".net" -> (0.0, 0.0, 0.0),
"JVM" -> (0.2, 0.1, 0.0),
"JNI" -> (0.2, 0.5, 0.8),
"Unity3D" -> (0.0, 0.0, 0.0),
"Unreal" -> (0.0, 0.0, 0.0),
"Marmalade" -> (0.0, 1.0, 1.0),
"ASM" -> (0.2, 0.1, 0.0),
"Reverse Enigneering" -> (0.5, 0.0, 0.0),
"Computer Design" -> (0.2, 0.1, 0.0),
"Electronics" -> (0.0, 0.0, 0.0),
"LaTeX" -> (0.8, 0.3, 0.2),
"Qt" -> (0.5, 0.5, 0.2),
"UI" -> (0.1, 0.3, 0.5),
"UX" -> (0.1, 0.0, 0.0),
"WebGL" -> (0.1, 0.0, 0.0),
"Network Client" -> (0.5, 1.0, 0.9),
"Test Automation" -> (0.5, 0.2, 0.0),
"Economy" -> (0.0, 0.0, 0.0),
"ssh" -> (1.0, 0.5, 0.9),
"Network Stack" -> (0.3, 0.2, 0.0),
"Device Drivers" -> (0.1, 0.0, 0.0),
"nginx" -> (1.0, 0.5, 0.1),
"Tomcat" -> (0.0, 0.0, 0.0)
)
val technologiesPerDomain: List[Int] = domains
.map { domain =>
val techs = domain._2._1
techs.size
}
.toList
val totalTechnologies: Int = technologies.size
val minTechnologiesPerDomain: Double = technologiesPerDomain.min.toDouble
val maxTechnologiesPerDomain: Double = technologiesPerDomain.max.toDouble
def avg(x: List[Double]): Double = if (x.length > 0) x.sum / x.length.toDouble
else 0.0
def popularity(technology: String, domainStream: Stream[(String, (Set[String], Double))] = domains.toStream, count: Int = 0): Double = domainStream match {
case head #:: tail =>
val techs = head._2._1
val technologyMatch = techs contains technology
val newCount = if (technologyMatch) count + 1
else count
popularity(technology, domainStream.tail, newCount)
case Stream() =>
if (totalTechnologies == 0) 0.0
else count.toDouble / totalTechnologies.toDouble
}
def gradeSimplicity(domain: String): Double = {
val technologiesPerDomain = domains(domain)._1.size.toDouble
1.0 - (technologiesPerDomain - minTechnologiesPerDomain) / maxTechnologiesPerDomain
}
val domainsGrades: Iterable[(String, Double, Double, Double, Double, Double)] = for {
(domain, (domainTechs, domainInterest)) <- domains
domainTechsList = domainTechs.toList
techInterest = avg(domainTechsList map { technologies(_)._1 })
knowledge = avg(domainTechsList map { technologies(_)._2 })
xp = avg(domainTechsList map { technologies(_)._3 })
simplicity = gradeSimplicity(domain)
} yield (domain, techInterest, domainInterest, knowledge, xp, simplicity)
val technologiesGrades: Iterable[(String, Double, Double, Double, Double)] = for {
(technology, (interest, knowledge, xp)) <- technologies
} yield (technology, interest, knowledge, xp, popularity(technology))
val titleFormatLength = 25
val columnDelimiterLength = 2
val columnLength = 13
val columnDelimiter = " " * columnDelimiterLength
def titleFormatted(title: String): String = {
val whiteSpace: String = " " * (titleFormatLength - title.length)
val out: String = (title take titleFormatLength) ++ whiteSpace
out
}
def valueFormatted(value: Double): String = f"${value * 100.0}%2.0f%%"
def rowString(ls: List[String]): String = {
ls.zipWithIndex.flatMap {
case (text: String, index: Int) =>
val t = if (index == 0) text
else text take columnLength
val whiteSpace = " " * (columnLength - t.length)
t +: whiteSpace +: columnDelimiter
}
}
.mkString
.trim
def gradeRow(title: String, grades: List[Double]): String = {
val allGrades = grades :+ avg(grades)
val row = titleFormatted(title) +: (allGrades map valueFormatted)
rowString(row)
}
def printDomains(): Unit = {
def printCaption(): Unit = {
val caption = List(titleFormatted("domain"), "tech.interest", "dom.interest", "knowledge", "xp", "simplicity", "average")
val rowStr = rowString(caption)
val underline = "-" * rowStr.length
println("Domains")
println(rowStr)
println(underline)
}
def printTable(): Unit =
domainsGrades
.toList
.sortBy { x: (String, Double, Double, Double, Double, Double) => (x._2 + x._3 + x._4 + x._5 + x._6) }
.reverse
.map { case (domain, techInterest, domainInterest, knowledge, xp, simplicity) =>
gradeRow(domain, List(techInterest, domainInterest, knowledge, xp, simplicity))
}
.foreach { println(_) }
printCaption()
printTable()
}
def printTopTechnologies(): Unit = {
val n = 20
def printCaption(): Unit = {
val caption = List(titleFormatted("technology"), "interest", "knowledge", "xp", "pop", "average")
val rowStr = rowString(caption)
val underline = "-" * rowStr.length
println(s"Top $n Technologies")
println(rowStr)
println(underline)
}
def printTable(): Unit =
technologiesGrades
.toList
.sortBy { x: (String, Double, Double, Double, Double) => (x._2 + x._3 + x._4 + x._5) }
.reverse
.take(n)
.map { case (technology, interest, knowledge, xp, popularity) =>
gradeRow(technology, List(interest, knowledge, xp, popularity))
}
.foreach { println(_) }
printCaption()
printTable()
}
printDomains()
println()
printTopTechnologies()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment