Skip to content

Instantly share code, notes, and snippets.

@v2keener
Last active August 29, 2015 14:08
Show Gist options
  • Save v2keener/b73570fb86b22fd3792d to your computer and use it in GitHub Desktop.
Save v2keener/b73570fb86b22fd3792d to your computer and use it in GitHub Desktop.
(*
This is a command-line app that allows you to type whatever you want and get [Yes|No|[Maybe]] as an answer.
It also creates log files, one for each day, and one for each month.
This file compiles with:
fsc.exe bit.fs --standalone
*)
//#r "PresentationCore.dll"
open System
open System.IO
open System.Text
open System.Text.RegularExpressions
open System.Windows.Forms
module BitEchoer =
// Utility functions
let getTimeStamp() = DateTime.Now.ToString("yyyyMMdd HH:mm:ss")
let getFilePath() =
let args = System.Environment.GetCommandLineArgs()
if args.Length > 1 then
args.[1]
else
null
let writeToClipboard(data: string) =
try
Clipboard.SetData(DataFormats.Text, data) |> ignore
with
| x -> Console.WriteLine("¡Error writing to clipboard!" + x.ToString())
//finally ()
let writeFileData(path, data) =
if String.IsNullOrWhiteSpace(path) = false then
// Write out what the user wants, NOT overwriting anything in the file
File.AppendAllText(path, data)
else
try File.AppendAllText(DateTime.Now.ToString("yyyyMMdd") + "-bit.txt", data)
finally ()
// End Utility functions
type LogPrinter() =
let logStore = new StringBuilder()
let logFilename = DateTime.Now.ToString("yyyyMM") + " bit log file.txt"
member x.logn (text: string) =
logStore.AppendLine text |> ignore
member x.logEndDate (text: string) =
logStore.Replace("{EndDate}", text) |> ignore
member x.getLogStore() = logStore
member x.WriteLog() =
// Attempt log storage
try File.AppendAllText(logFilename, logStore.ToString())
finally ()
// End LogPrinter
type LinePrinter() =
let lineText = new StringBuilder()
let startTimeText = getTimeStamp()
let printFn(text:string, newLine) =
if newLine then
printfn "%s" text
lineText.AppendLine text |> ignore
else
printf "%s" text
lineText.Append text |> ignore
member x.printn(text) =
printFn(text, true) |> ignore
member x.print(text) =
printFn(text, false) |> ignore
member x.getLineText() = lineText
member x.getStartTime() = startTimeText
member x.Clear() = lineText.Clear()
// End LinePrinter
type NextAnswer() =
// Vars and private methods
let r = new Random()
let lp = new LinePrinter()
let log = new LogPrinter()
let helpText = "\r\nHit 'q', 'Q', or type 'quit' to exit...\r\n"
let questionText = "Ask your question:\r\n\t"
let logLineFormat = "{BeginDate}::{EndDate}::{Question}::{Answer}"
let quitRegex = "^([qQ]|([qQ][uU][iI][tT]))$"
let ynRegex = "^([yY]\\/[nN]|[Yy][Nn]).*"
let tfRegex = "^([tT]\\/[fF]|[Tt][Ff]).*"
let quittingMsg = "\r\nQuitting...\r\n\tDone"
let matchesRegex(text, regexpStr) =
Regex.IsMatch(text, regexpStr)
// Iteration method (equiv to a while loop)
let rec NextAnswerIter firstTime =
let mutable next:int = -1
if firstTime then
lp.Clear() |> ignore
lp.printn (lp.getStartTime())
lp.printn helpText
lp.print questionText
let questionStr = Console.ReadLine()
lp.getLineText().AppendLine questionStr |> ignore
let isQuitting = matchesRegex(questionStr, quitRegex)
let isYN = matchesRegex(questionStr, ynRegex)
let isTF = matchesRegex(questionStr, tfRegex)
let isBinary = isYN || isTF
match (isQuitting, isBinary) with
| (true, _) ->
lp.printn quittingMsg
let endTimeText = getTimeStamp()
lp.printn endTimeText
log.logEndDate endTimeText
let filepathText = getFilePath()
let fileData = lp.getLineText().ToString() + "\r\n\r\n"
writeToClipboard(fileData)
writeFileData(filepathText, fileData)
log.WriteLog() |> ignore
// Out
//lp.getLineText().ToString()
| (_, true) ->
next <- r.Next(2)
| _ ->
next <- r.Next(3)
if not isQuitting then
lp.print "\tAnswer: "
let yesText = if isTF then "True" else "Yes"
let noText = if isTF then "False" else "No"
let answer =
match next with
| 0 -> yesText
| 1 -> noText
| 2 -> "Maybe"
| _ -> "!!ERROR!! next value of " + next.ToString() + " is invalid"
lp.printn (answer + "\r\n")
let logText =
logLineFormat.Replace("{BeginDate}", lp.getStartTime())
.Replace("{Question}", "Ask your question: " + questionStr)
.Replace("{Answer}", "Answer: " + answer)
log.logn(logText)
// Recurse (tail recursion should work for this)
NextAnswerIter false
member x.Start() = NextAnswerIter true
// END NextAnswer()
[<EntryPoint>][<STAThread>]
let main args =
// Run
let d = new BitEchoer.NextAnswer()
d.Start()
0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment