Last active
December 25, 2016 21:24
-
-
Save alopatindev/9fa774c7a375b1772083fc976f6ce168 to your computer and use it in GitHub Desktop.
Domain selection tool based on interest in technologies the domain relates to
This file contains hidden or 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
// 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