F# Optional CSV load - f#

I'm using the F# data provider to load csv files. For some reason, not in my control, they occasionally change the file to a gzip. (e.g. MyFile.txt could also be MyFile.text.gz)
So, I have this and it works just fine
let fl = CSV.load("MyFile.txt")
What I need to be able to do is if this errors with file not found, I need it to look for the alternate name.
let fl = CSV.load("MyFile.txt.gz")
I've tried a try...with block
try
let fl = CSV.load("MyFile.txt")
with
let fl = CSV.load("MyFile.txt.gz")
It won't let me use let keyword in this fashion. I even tried
try
let fl = CSV.load("MyFile.txt")
with
CSV.load("MyFile.txt.gz") -> fl
With C#, this would be pretty straight forward. Thanks in advance for any assistance.

You can use something like:
let fl =
try CSV.load("MyFile.txt")
with _ -> CSV.load("MyFile.txt.gz")
But I believe a better solution would be to check if the file exists first.

Related

Using vimscript plugin in lua neovim

I tried to use this simple script (its not from me) for simple reading a file and adding its content to a plugin called projectionist: https://github.com/tpope/vim-projectionist
(The original script: https://github.com/andyl/vim-projectionist-elixir/blob/master/ftdetect/elixir.vim)
I didn't find any api for reading a file in lua nvim. The error in the picture targets the line let l:json = readfile(s:proj_jsn) so I assume that this api is not available by lua?
if vim.g.loaded_vim_projectionist then
return
end
vim.g.loaded_vim_projectionist = 1
vim.api.nvim_exec([[
let s:base_dir = resolve(expand("<sfile>:p:h"))
let s:proj_jsn = s:base_dir . "/projections.json"
function! s:setProjections()
let l:json = readfile(s:proj_jsn)
let l:dict = projectionist#json_parse(l:json)
call projectionist#append(getcwd(), l:dict)
endfunction
call s:setProjections()
]], false)
The error message (picture)
I checked a several times if the file projections.json is in the right place, so this is not the mistake.
Thank you all in advance.

Does Swift allow a quick try-else construct?

I want to do something like
doc = try? Doc(url) else Doc()
Is there a way to do something clean like that without much ado? I tried
doc = try? Doc(url) : Doc()
But that didn't work

How to reuse the web client for HtmlProvider?

I load multiple pages using the same type provider, HtmlProvider:
type Article = HtmlProvider<"https://en.wiktionary.org/wiki/giraffe">
let sheepArticle = Article.Load "https://en.wiktionary.org/wiki/sheep"
let koalaArticle = Article.Load "https://en.wiktionary.org/wiki/koala"
let pandaArticle = Article.Load "https://en.wiktionary.org/wiki/panda"
...
Is it anyhow possible to configure the provider so that the web client underneath is reused there?
I haven't found nothing on that in the docs. I do a lot of similar calls, so that would be a significant optimization.
There is no way to configure the HtmlProvider to do this automatically behind the scenes, but you can easily create your own WebClient to download the pages and then use the Parse method of the provided type (rather than using Load to download and parse it):
type Article = HtmlProvider<"https://en.wiktionary.org/wiki/giraffe">
let wc = new WebClient()
let sheepArticle = Article.Parse(wc.DownloadString("https://en.wiktionary.org/wiki/sheep"))
let koalaArticle = Article.Parse(wc.DownloadString("https://en.wiktionary.org/wiki/koala"))
let pandaArticle = Article.Parse(wc.DownloadString("https://en.wiktionary.org/wiki/panda"))

Open a picture (jpg.) in F#

I would like to open several pictures (.jpg) with F#.
All my pictures are stored in afile (filepath). I would like to show them to the user.
How can I do this using F#?
To open one picture, it tried something like :
open System.IO
let editPicture filepath =
let fileStream = File.Open(filepath,FileMode.Open)
fileStream.Visible <- True
but it doesn t work.
Here is a minimal quick and dirty WinForms F# snippet that shows a .jpg image on a screen:
open System
open System.Windows.Forms
open System.Drawing
let form = new Form()
let pb = new PictureBox()
pb.Image <- Image.FromFile(path-to-file-with-your-jpg-image)
pb.SizeMode <- PictureBoxSizeMode.AutoSize
form.Controls.Add(pb)
[<STAThread>]
do
Application.Run(form)
This may give you some initial traction and feel on what is involved into reaching your goal. But overall I agree with Carsten König that learning curve for doing UIs with F# is quite steep.

strip carriage returns from xml serialization in F#

update: some background - i use the xml file to generate a set of pdfs (through a java application that drives JasperReports). all the reports are coming out blank when I use this new xml file. I've ruled out network problems because I use an old xml file from the same server that I run the java application with the new xml file. I've compared the two files (old-good one and new-bad one) using a hex-editor and my first clue is that there are carriage returns in the new file and none in the old one. this may not fix the issue, but I'd like to eliminate it from the equation.
I think I need to remove all the carriage returns from my xml file in order for it to work as I need it to. In my travels, the closest I found is this:
.Replace("\r","")
but where do I use it in the following code? I create my data model, create a root, and pass that to the serializer. At what point can I say "remove carriage returns?"
let def = new reportDefinition("decileRank", "jasper", new template("\\\\server\\location\\filename.jrxml", "jrxml"))
let header = new reportDefinitions([| def |])
let root = reportGenerator(header, new dbConnection(), new reports(reportsArray))
let path = sprintf "C:\\JasperRpt\\parameter_files\\%s\\%d\\%s\\%s\\" report year pmFirm pmName //(System.DateTime.Now.ToString("ddMMyyyy"))
Directory.CreateDirectory(path) |> ignore
let filename = sprintf "%s%s" path month
printfn "%s" filename
use fs = new FileStream(filename, FileMode.Create)
let xmlSerializer = XmlSerializer(typeof<reportGenerator>)
xmlSerializer.Serialize(fs,root)
fs.Close()
XmlWriterSettings has some options for formatting the output, so pass the output through XmlWriter.
You should be able to something like this (don't have FSI at hand right now, don't know if it compiles. :)
//use fs = new FileStream(filename, FileMode.Create)
let settings = new XmlWriterSettings();
settings.Indent <- true;
settings.NewLineChars <- "\n";
use w = XmlWriter.Create(filename, settings);
let xmlSerializer = XmlSerializer(typeof<reportGenerator>)
xmlSerializer.Serialize(w,root)
It's probably not the best solution, but you could try
// after your current code
let xmlString = File.ReadAllText filename
ignore( File.WriteAllText( filename , xmlString.Replace("\r","")))

Resources