17 changed files with 376 additions and 14 deletions
@ -0,0 +1,19 @@
|
||||
module internal DataAccess |
||||
|
||||
open System |
||||
open System.IO |
||||
|
||||
let CreateSampleTextFilesPath = __SOURCE_DIRECTORY__ + "\\TextFiles\\" |
||||
|
||||
let FindSampleTextFiles path = |
||||
Directory.GetFiles(path, "*", SearchOption.TopDirectoryOnly) |
||||
|
||||
let ListSampleFiles = |
||||
CreateSampleTextFilesPath |
||||
|> FindSampleTextFiles |
||||
|
||||
let SelectRandomSampleFile = |
||||
let files = ListSampleFiles |
||||
files.[Random().Next(0, files.Length)] |
||||
|
||||
let LoadFile path = File.ReadAllText(path) |
@ -0,0 +1,8 @@
|
||||
module internal DataCleaning |
||||
|
||||
open System.IO |
||||
open System.Text.RegularExpressions |
||||
|
||||
let ReplaceArtifact pattern text = Regex.Replace(text, pattern, " ") |
||||
|
||||
let SplitText pattern text = Regex.Split(text, pattern) |
@ -0,0 +1,26 @@
|
||||
module internal DataProcessing |
||||
|
||||
open System.Text.RegularExpressions |
||||
open DataCleaning |
||||
open System |
||||
|
||||
let MatchText pattern text = Regex.IsMatch(text, pattern) |
||||
|
||||
let ConcatToString words = String.concat " " words |
||||
|
||||
let SortIntoGroups groupSize text = |
||||
SplitText @"\s+" text // Splits text where there is a space. |
||||
|> Seq.windowed groupSize |
||||
|
||||
let BisectWords words = |
||||
let length = Array.length words |
||||
let start = |
||||
words |
||||
|> Seq.take (length - 1) |
||||
|> ConcatToString |
||||
(start, words.[length - 1]) |
||||
|
||||
let CombineWords prev next = |
||||
[prev; next] |
||||
|> List.filter(fun s -> not (String.IsNullOrWhiteSpace s)) |
||||
|> ConcatToString |
@ -0,0 +1,34 @@
|
||||
module internal DataServices |
||||
|
||||
open SystemServices |
||||
open System |
||||
open DataStructuring |
||||
open DataProcessing |
||||
open DataCleaning |
||||
|
||||
let PickRandomWord words = PickRandomItem (Random().Next) words |
||||
|
||||
let rec GenerateMarkovChain (map: Map<string, string List>) (state:string) chain = |
||||
let nextChoice = map.[state] |> PickRandomWord |
||||
if MatchText @"\." nextChoice then nextChoice :: chain |
||||
else |
||||
let currentWords = |
||||
state |
||||
|> SplitText @"\s+" |
||||
|> Seq.skip 1 |
||||
|> ConcatToString |
||||
GenerateMarkovChain map (CombineWords currentWords nextChoice) (nextChoice :: chain) |
||||
|
||||
let GenerateMarkovSentence map start = |
||||
GenerateMarkovChain map start [start] |
||||
|> List.rev |
||||
|> ConcatToString |
||||
|
||||
let GenerateMarkovText noOfSentences map = |
||||
let startWords = fst(SeperateStartWords map) |
||||
let result = |
||||
seq { |
||||
for i in 0 .. noOfSentences do |
||||
yield GenerateMarkovSentence map (PickRandomWord startWords).Key |
||||
} |
||||
result |> ConcatToString |
@ -0,0 +1,23 @@
|
||||
module internal DataStructuring |
||||
|
||||
open DataProcessing |
||||
|
||||
let UpdateMap (map:Map<_,_>) key value = |
||||
if map.ContainsKey key then |
||||
let exisitingValue = map.[key] |
||||
let map = map |> Map.remove key |
||||
map |> Map.add key (value :: exisitingValue) |
||||
else |
||||
map.Add (key, [value]) |
||||
|
||||
// Not the best name... |
||||
let ConstructMap map text = |
||||
BisectWords text ||> UpdateMap map |
||||
|
||||
let GenerateMap<'a> = Seq.fold ConstructMap Map.empty |
||||
|
||||
let SeperateStartWords map = |
||||
let startWords = |
||||
map |
||||
|> Map.partition (fun k _ -> MatchText @"^[A-Z]" k) |
||||
startWords |
@ -1,4 +0,0 @@
|
||||
namespace WetPancake |
||||
|
||||
type Class1() = |
||||
member this.X = "F#" |
@ -0,0 +1,28 @@
|
||||
namespace WetPancake |
||||
|
||||
module Pancake = |
||||
|
||||
open System |
||||
open SystemServices |
||||
open DataAccess |
||||
open DataCleaning |
||||
open DataProcessing |
||||
open DataStructuring |
||||
open DataServices |
||||
|
||||
let RequestRandomText = |
||||
let dss_text = |
||||
LoadFile SelectRandomSampleFile |
||||
|> ReplaceArtifact "\"" |
||||
|> ReplaceArtifact "\n\nIn" |
||||
|> ReplaceArtifact "\r" |
||||
|> ReplaceArtifact "\n" |
||||
|> SplitText @"\s+" |
||||
|> ConcatToString |
||||
|> SortIntoGroups 10 |
||||
|> GenerateMap |
||||
GenerateMarkovText 2 dss_text |
||||
|
||||
//let RequestText (gibberishLevel: int) (sentences: int) |
||||
|
||||
//let RequestTextFromFile (gibberishLevel: int) (sentences: int) (filePath: string) |
@ -1,8 +1,120 @@
|
||||
// Learn more about F# at http://fsharp.org |
||||
// See the 'F# Tutorial' project for more help. |
||||
|
||||
#load "Library1.fs" |
||||
open WetPancake |
||||
#load "SystemServices.fs" |
||||
#load "DataAccess.fs" |
||||
#load "DataCleaning.fs" |
||||
#load "DataProcessing.fs" |
||||
#load "DataStructuring.fs" |
||||
#load "DataServices.fs" |
||||
#load "ProductServices.fs" |
||||
|
||||
// Define your library scripting code here |
||||
open System |
||||
open SystemServices |
||||
open DataAccess |
||||
open DataCleaning |
||||
open DataProcessing |
||||
open DataStructuring |
||||
open DataServices |
||||
|
||||
// System Services |
||||
let ss_number = PickRandomNumber 10 |
||||
let ss_item = |
||||
let items = seq {1 .. 10} |
||||
PickRandomItem (Random().Next) items |
||||
|
||||
|
||||
// Data Access |
||||
let da_sampleFilePath = CreateSampleTextFilesPath |
||||
let da_sampleTextFiles = FindSampleTextFiles da_sampleFilePath |
||||
let da_sampleFiles = ListSampleFiles |
||||
let da_randomSampleFile = SelectRandomSampleFile |
||||
let da_file = LoadFile da_randomSampleFile |
||||
|
||||
// Data Cleaning |
||||
let dc_replace1 = ReplaceArtifact "\"" "dc_repl1 \" end." |
||||
let dc_replace2 = ReplaceArtifact "\n\nIn" "dc_repl2 \n\nIn end." |
||||
let dc_replace3 = ReplaceArtifact "\r" "dc_repl3 \r end." |
||||
let dc_replace4 = ReplaceArtifact "\n" "dc_repl4 \n end." |
||||
let dc_replace5 = |
||||
let testPath = "a1 \" a2 \n\nIn a3 \r a4 \n end." |
||||
testPath |
||||
|> ReplaceArtifact "\"" |
||||
|> ReplaceArtifact "\n\nIn" |
||||
|> ReplaceArtifact "\r" |
||||
|> ReplaceArtifact "\n" |
||||
let dc_split = SplitText @"\s+" "This is a test string." |
||||
|
||||
// Data Processing |
||||
let dp_isStart = MatchText @"^[A-Z]" "This is a test" |
||||
let dp_isEnd = MatchText @"\." "and the end is nigh." |
||||
let dp_failStart = MatchText @"^[A-Z]" "somewhere in the middle" |
||||
let dp_failEnd = MatchText @"\." "this is not the end" |
||||
let dp_words = |
||||
let words = ["This"; "is"; "a"; "test"; "."] |
||||
ConcatToString words |
||||
let dp_words2 = |
||||
let words = "This is a test. And has serveral words in it." |
||||
SortIntoGroups 2 words |
||||
|> Seq.toList |
||||
let dp_bisect = |
||||
let words = [|"This"; "is"; "a"; "test"; "."; "Contains"; "text"; "."|] |
||||
BisectWords words |
||||
let dp_combine = |
||||
let prev = "This is the previous" |
||||
let next = "this is the next" |
||||
CombineWords prev next |
||||
let dp_combine2 = |
||||
let prev = " " |
||||
let next = "Prev is whitespace" |
||||
CombineWords prev next |
||||
let dp_combine3 = |
||||
let prev = "Next is empty" |
||||
let next = "" |
||||
CombineWords prev next |
||||
let dp_combine4 = |
||||
let prev = "Next is null" |
||||
let next = null |
||||
CombineWords prev next |
||||
|
||||
// Data Structuring |
||||
let ds_map = Map.empty |
||||
let ds_text = [|"This"; "is"; "a"; "test"; "string."|] |
||||
let ds_map2 = |
||||
let text = BisectWords ds_text |
||||
let result = UpdateMap ds_map (fst(text)) (snd(text)) |
||||
result |
||||
let ds_map3 = ConstructMap ds_map ds_text |
||||
let ds_text2 = [ |
||||
[|"This"; "is"; "the"; "first"; "test"; "string."|] |
||||
[|"This"; "is"; "the"; "first"; "test"; "string."|] |
||||
[|"this"; "is"; "the"; "second"; "test"; "string"|] |
||||
[|"this"; "is"; "the"; "third"; "test"; "string"|] |
||||
] |
||||
let ds_map4 = ConstructMap ds_map ds_text2.[1] |
||||
let ds_map5 = [for i in ds_text2 -> ConstructMap ds_map i] |
||||
let ds_map6 = |
||||
let result = |
||||
[for item in ds_map5 do |
||||
for i in item -> i] |
||||
result |
||||
let ds_map7 = |
||||
let result = |
||||
[for item in ds_map5 -> SeperateStartWords item] |
||||
result |
||||
let ds_map7Item = ds_map7.Item(0) |
||||
|
||||
// Data Services |
||||
let dss_text = |
||||
LoadFile SelectRandomSampleFile |
||||
|> ReplaceArtifact "\"" |
||||
|> ReplaceArtifact "\n\nIn" |
||||
|> ReplaceArtifact "\r" |
||||
|> ReplaceArtifact "\n" |
||||
|> SplitText @"\s+" |
||||
|> ConcatToString |
||||
|> SortIntoGroups 2 |
||||
|> GenerateMap |
||||
//let dss_startwords = SeperateStartWords dss_text |
||||
let dss_sentences = GenerateMarkovText 2 dss_text |
||||
printfn "Text: %A" dss_sentences |
@ -0,0 +1,9 @@
|
||||
module internal SystemServices |
||||
|
||||
open System |
||||
|
||||
let PickRandomNumber max = Random().Next(0, max); |
||||
|
||||
let PickRandomItem (rnd: int -> int) seq = |
||||
let index = rnd (Seq.length seq) |
||||
seq |> Seq.item index |
@ -0,0 +1,21 @@
|
||||
That's right, you've won. Well done and come on down, today is not your lucky day. It's -- in fact -- the best day of your life. How else can you describe the moment you discovered the Console.Waterworks NuGet package? That's right, you can't. So, let's get on with basking in your glory. I can't wait. |
||||
|
||||
First of all, Console.Waterworks is for writing extendable command-based console programs. Gone are the days where you need to parse user input and write error handling code. You now have the ability to write methods which act as commands at run-time. Method parameters are, also, accepted and parsed at run-time. This is brilliant and in need of a demonstration. Are you ready to see something which surpasses the hype and majesty of the sun herself? Well, come on then. It's demo. time. |
||||
|
||||
As you can see in the Gif. above, the method I have written (on the left) maps to a command in the console program at run-time (on the right). There is no parsing of user input or error handling in the code, either. Don't worry, you'll be reading more about that majestic trick-shot in a moment. For now, enjoy the flashing lights. You've earned it. |
||||
|
||||
We both know you're not an idiot. So, when you recognise the brilliance, you know it's one-hundred percent legitimate. This is a fair assessment. And, this next intellectual marvel will elevate your core being to a state of ecstasy. Yes, you're right. I'm about to render you stupid through the sheer splendour of intellectual stimulation. It's going to be so strong, you might consider it a form of infidelity. Let's hope you can keep your wits about you. This is your relationship at risk here, not mine. Come on you little cupcake. Let's demo. |
||||
|
||||
This demo. is the one about the error handling I mentioned earlier. As you can see in the Gif., the method doesn't have any error handling code. But, the console program displays an error message to the user. Yes, you're right. It's brilliant. |
||||
|
||||
This next demo. is where everything changes, though. I hope you've strapped your pants on tight. |
||||
|
||||
In a moment as clear as crystal, what you’re looking at is a self-documenting "help" section. This means you no longer need to write a help guide -- from scratch -- in every console program. You can now add Waterworks custom attributes to the methods you want to declare at run-time. Console.Waterworks will make a note of those attributes and display them like the demo. shows. |
||||
|
||||
Everything above is brilliant and has a place on this Earth and you know this. Like I said before, you're not an idiot. So, the next time you're writing a console program, don't forget to add Console.Waterworks to your solution. |
||||
|
||||
For more information about using Console.Waterworks in your solution, head to the GitHub. Console.Waterworks is available as a .Net and .Net Core NuGet package. |
||||
|
||||
Thank you for your time and I look forward to your words of recommendation about me reach me. And, when I say "reach me", I don't me via you. I mean via other people talking about you and on your behalf. |
||||
|
||||
Thanks again. |
@ -0,0 +1,45 @@
|
||||
using Console.Waterworks; |
||||
using Console.Waterworks.Attributes; |
||||
using System; |
||||
using WetPancake; |
||||
//using WetPancake; |
||||
using static System.Environment; |
||||
|
||||
namespace WetPancakeCLI |
||||
{ |
||||
public static class ConsoleCommands |
||||
{ |
||||
[ListCommand] |
||||
[Description("Prints a test messge to the console.")] |
||||
[Parameters("none")] |
||||
[Usage("> Test")] |
||||
public static string Test() => "SUCCESS: Console.Waterworks is wired into Wet Pancake CLI."; |
||||
|
||||
[ListCommand] |
||||
[Description("Lists out the commands this program offers.")] |
||||
[Parameters("none")] |
||||
[Usage("> Help")] |
||||
public static string Help() => new CW_Liaison().RequestHelpDocumentation("WetPancakeCLI"); |
||||
|
||||
[ListCommand] |
||||
[Description("Exits out of the program.")] |
||||
[Parameters("none")] |
||||
[Usage("> Exit")] |
||||
public static void Exit() => Environment.Exit(ExitCode); |
||||
|
||||
[ListCommand] |
||||
[Description("Generates random text, the number of sentences generated is determined by the user.")] |
||||
[Parameters("int: sentenences")] |
||||
[Usage("> GenerateRandomText")] |
||||
public static string GenerateRandomText(int sentences) |
||||
{ |
||||
var result = Pancake.RequestRandomText; |
||||
return result; |
||||
} |
||||
|
||||
public static string test1() |
||||
{ |
||||
return "This is a test method for quickly testing things out"; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<packages> |
||||
<package id="Console.Waterworks" version="0.1.0.0-alpha1" targetFramework="net471" /> |
||||
</packages> |
After Width: | Height: | Size: 178 KiB |
Loading…
Reference in new issue