#load a package in F# interactive (FSharpChart.fsx) - f#

Hi i'm a noob and asking this newbie question, please forgive me.
I've installed successfully FSharpChart in my local directory
...
Added package 'MSDN.FSharpChart.dll.0.60.0' to folder 'C:\Users\Fagui\Documents\GitHub\Learning Fsharp\Expert in F\packages'
Added package 'MSDN.FSharpChart.dll.0.60.0' to 'packages.config'
Successfully installed 'MSDN.FSharpChart.dll 0.60.0' to Expert in F
now, if i do
#load "FSharpChart.fsx";;
^^^^^^^^^^^^^^^^^^^^^^^
stdin(4,1): error FS0078: Unable to find the file 'FSharpChart.fsx' in any of
C:\Users\Fagui\AppData\Local\Temp
additional info:
inside this folder, i see a nupkg file, and a lib directory
Inside the lib directory, there is a dll, and a pdf file,
but i don't see any .fsx file.
basically, F# has installed the package in the active folder for the current project, and F#interactive is in another folder ?? bit strange ?
should i install another time the package ? or what is the way around it ?
thanks
UPDATE:
i don't know why, but apparently when i installed the FSharpChart package, I only got the dll, no fsx file
i managed to load it doing
#I #"C:\Users\Fagui\Documents\GitHub\Learning Fsharp\Expert in F"
#r #"packages\MSDN.FSharpChart.dll.0.60\lib\MSDN.FSharpChart.dll";;
unfortunately, typing the script in F# interactive
open MSDN.FSharp.Charting
let rnd = System.Random()
let rand() = rnd.NextDouble()
let randomPoints = [for i in 0 .. 1000 -> 10.0 * rand(), 10.0 * rand()]
randomPoints |> FSharpChart.Point;;
doesn't yield any chart, but just returns a list
val rnd : Random
val rand : unit -> float
val randomPoints : (float * float) list =
[(9.765916457, 2.272289941); (0.8211438594, 1.625466995);
...
(7.783786034, 7.572208311); (6.497914692, 3.66987128); ...]
val it : ChartTypes.PointChart
this may be due to the fact that the library is not supported anymore, and that i should use a newer library like Thomas Petricek indicated.
So, i did manage to install FSharp.Charting instead
let rnd = System.Random()
let rand() = rnd.NextDouble()
let randomPoints = [for i in 0 .. 1000 -> 10.0 * rand(), 10.0 * rand()]
randomPoints |> Chart.Point;;
and it did work

There is a newer version of the FSharpChart.fsx library which is called F# Charting, so first of all, I would recommend using this newer library instead (the API is quite similar, but F# Charting has a number of improvements).
The documentation for F# Charting also has a detailed page on referencing the library.
Typically, when you reference the library using NuGet, you'll need to specify relative reference:
// On Mac OSX use packages/FSharp.Charting.Gtk.0.90.13/FSharp.Charting.Gtk.fsx
#load "packages/FSharp.Charting.0.90.13/FSharp.Charting.fsx"
Where 0.90.13 is the version of the library that you got from NuGet (you may need to check the folder name - the path references in #load are relative to the place where your script lives).

Yes, F# Interactive is independent of the current project.
Use:
#load #"C:\Users\Fagui\Documents\GitHub\Learning Fsharp\Expert in F\packages\FSharpChart.fsx";;
Also you can use the #I directive if you need to reference assemblies of a specific folder, see the reference.

Related

Importing FSharp.Charting in .fs file fails

Create a new FSharp Console project via VS2015
Add FSharp.Data and FSharp.Charting nuget package.
In Program.fs import both the packages
open FSharp.Charting
open Fsharp.Data
After the import I am able to use functions provided in FSharp.Data package but not in FSharp.Charting.
NOTE: In case of script (.fsx) file, which created in the same project, I am able to use both after adding their reference.
I just wanted to to know if there are any steps i am missing for adding any reference in a .fs file. If yes then why does it work with respect to FSharp.Data package.
I think if you search SO you'll find a few examples of displaying charts with FSharp.Charting. It's not exactly clear what sort of error are you getting. Assuming you are on Windows this should work:
open FSharp.Charting
open System
[<STAThread>]
[<EntryPoint>]
let main argv =
Chart.Line [ for x in 0 .. 10 -> x, x*x ] |> Chart.Show
printfn "%A" argv
0 // return an integer exit code
You will need to add references to System.Windows.Forms, System.Windows.Forms.DataVisualization and System.Drawing.

Meaning of CsvProvider error "The given key was not present in the dictionary" when trying to load sample file?

I am having trouble loading the csv files with FSharp.Data csv provider provided by fslab, including the sample adwords.csv file.
What does this error below mean? Also, when I hover over the code in the Visual studio editor it mentions that "The given key was not present in the dictionary"
Problem example:
#load "packages/FsLab/FsLab.fsx"
open System.IO
open FSharp.Data
"adwords.csv"
|> File.ReadAllLines
let test = CsvProvider<"adwords.csv">.GetSample()
The output:
>
val it : string [] =
[|"Criteria ID,Name,Canonical Name,Parent ID,Country Code,Target Type,Status";
"1000010,Abu Dhabi,"Abu Dhabi,Abu Dhabi,United Arab Emirates",9041082,AE,City,Active";
"1000011,Ajman,"Ajman,Ajman,United Arab Emirates",9047096,AE,City,Active";
"1000012,Al Ain,"Al Ain,Abu Dhabi,United Arab Emirates",9041082,AE,City,Active";
"1000013,Dubai,"Dubai,Dubai,United Arab Emirates",9041083,AE,City,Active";
"2004,Afghanistan,Afghanistan,,AF,Country,Active"|]
>
>System.MethodAccessException: Attempt by method '<StartupCode$FSI_0007>.$FSI_0007.main#()' to access method 'FSharp.Data.Runtime.CsvFile`1<System.__Canon>.Create(System.Func`3<System.Object,System.String[],System.__Canon>,
at <StartupCode$FSI_0007>.$FSI_0007.main#() in C:\test.fsx:line 11
Stopped due to error
I ran into this problem with my own files, so I grabbed this sample file from here: https://raw.githubusercontent.com/fsharp/FSharp.Data/master/tests/FSharp.Data.Tests/Data/Adwords.csv
Debug info:
If I delete the FSharp.Data library folder (v 2.3.0) and replace with version 2.2.5 it works correctly with no error.
If I don't use the FsLab.fsx script and instead use
#I "packages/FSharp.Data/lib/net40
#r "FSharp.Data.dll"
then everything works.
The path to the FsLab.fsx script is correct, it runs when I send the line to fsi.
The F# version is 14.0.23413.0.
The version of FSharp.Data downloaded by FSlab is FSharp.Data.2.3.0.
I have no other references in the .fsx script.
I am using Visual Studio Community edition 14.0.24720.00 Update 1.
.NET version 4.6.01038
I am realizing now that I am not getting the popup asking if I want to allow the .dll like I think I used to get when I used this before.
There is nothing wrong with the file. This for example works:
#load #"..\..\FSLAB\packages\FsLab\FsLab.fsx"
open System.IO
open FSharp.Data
[<Literal>]
let csvFile = #"C:\tmp\adwords.csv"
File.Exists csvFile
type Csv = CsvProvider<csvFile>
let csv = Csv.Load(csvFile)
csv.Rows
There is something wrong with your FsLab of FSharp.Data installation or type providers security maybe. Try the following, specify the path to the file directly. If it still doesn't work just nuget FSharp.Data and try using the csv type provider directly in a new project.
Other info is also helpful. VS version, FSLab version, wha other references you have. etc.
EDIT: Thanks for the debug info. That's actually quite helpful. VS2015 Update 1 broke two things, the Binding Redirect for Fsharp and the type providers (that might have been FSharp Tools, I forgot). I would upgrade to Update 2. If that's not possible please check if your FSharp.Data.TypeProviders.dll is in C:\Program Files (x86)\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.3.0.0\Type Providers.
As referencing the dlls directly works, it's probably a version mismatch issue. My FsLab install predates VS2015 Update 1 and 2, so will see if it behaves differently with a new download.
There is some issue with the installation of FSharp.Data currently bundled with FsLab (as of June 2016). This issue is with version 2.3.0. If you instead use FSharp.Data 2.2.5 the code works as expected.
Delete the packages/FSharp.Data folder and replace with version 2.2.5. I did it from an old installation but you could do it from Nuget

Fsx execution path

I have a c# .net library I am looking to use within FSI/FSX. As part of the initialization of the .net lib, by default it expects and references a custom config file (MyAppConfig.xml) which loads various things before it can be used. When using it in c# it gets copied to the bin folder and the app by default expects it to be there and references it there unless there is a specific entry in the app.config to tell it otherwise. (I should add that it does it all by convention rather than injecting a path + filename, as per NLog, say)
I have an f# source file in a console app which will execute this initialization find, but I can't quite work out how to achieve this with FSI/FSX.
So my program.fs looks simply like
open System
open myApp
module Program =
[<EntryPoint>]
let Main(args) =
myApp.Initialization.Load() // references MyAppConfig.xml
Console.WriteLine("do my stuff!")
Console.ReadLine() |> ignore
0
If I try and do the same in FSI or using FSX, I have
#r #"E:\...path to MyApp...\MyApp.dll"
#I #"E:\...path to MyAppConfig.xml ..."
Environment.CurrentDirectory <- #"E:\...path to MyAppConfig.xml ..."
myApp.Initialization.Load() |> ignore // fails ... can't find MyAppConfig.xml
//do my stuff
I suspect that I've not got the paths quite right.
I'd be grateful of a steer
EDIT:
So I've managed to attach a debugger to the c# lib and see where it is looking for the config file - turns out it is "c:\Program Files\Microsoft F#\v4.0\" ( System.AppDomain.CurrentDomain.BaseDirectory) which again shows I've not quite understood how to tell FSI/FSX to use a particular path. If I copy the config file (MyAppConfig.xml) to that location it works fine.
Many thx
S
I'm not sure of the implications, but one possiblity might be temporarily changing the app base:
let origAppBase = AppDomain.CurrentDomain.BaseDirectory
AppDomain.CurrentDomain.SetData("APPBASE", "path_to_MyAppConfig.xml")
myApp.Initialization.Load() |> ignore
AppDomain.CurrentDomain.SetData("APPBASE", origAppBase) //restore original app base

How to implement a read table function in F#? (like Vlookup)

I need a function.
When I enter 0~15 and Protection, it'll return 45%.
Just like Vlookup function in Excel.
Is there a function like this one in F#?
(At website try F#, Learn -> Financial Modeling -> Using the Yahoo Finance Type Provider
It recommended us to use Samples.Csv.dll. However, I failed to install it and don't want to install that package just for a function :(.. )
I followed the tutorial (http://fsharp.github.io/FSharp.Data/library/CsvProvider.html)
and tried to run the program on my computer. But I am in trouble now
It couldn't identify the type CsvProvider (So I can't use the function Stocks.Load.)
What's the problem..?
This is how the code looks when using the CSV type provider in F# Data. To get this to work, you'll need to add reference to FSharp.Data.dll. The best way to do this is to install the package from NuGet. In Visual Studio, it will add reference for you, and in command line you can say:
nuget install FSharp.Data
Alternatively, if you are in an F# script file, then you need to install the nuget package and then add #r #"C:\path\to\FSharp.Data.dll". Then you can write the following:
open FSharp.Data
// Generate type based on a local copy with sample data
type Data = CsvProvider<"sample.csv">
// Load actual data from a file (this can be a different file with the same structure)
let loaded = Data.Load("runtime/file/name.csv")
// Find row for a specified age range & look at the properties
let row = loaded.Data |> Seq.find (fun r -> r.Age = "0~15")
row.Protection
row.Saving
row.Specified
A very simple way to do this is with a DataTable:
open System.Data
open System.IO
open LumenWorks.Framework.IO.Csv
let vlookup =
let table = new DataTable()
do
use streamReader = new StreamReader(#"C:\data.csv")
use csvReader = new CsvReader(streamReader, hasHeaders=true)
table.Load(csvReader)
table.PrimaryKey <- [|table.Columns.["Age"]|]
fun age (column: string) -> table.Rows.Find([|age|]).[column]
//Usage
vlookup "0~15" "Protection" |> printfn "%A"
There's no lack of CSV readers out there. I used this especially fast one (also available on NuGet).

Lua return directory path from path

I have string variable which represents the full path of some file, like:
x = "/home/user/.local/share/app/some_file" on Linux
or
x = "C:\\Program Files\\app\\some_file" on Windows
I'm wondering if there is some programmatic way, better then splitting string manually to get to directory path
How do I return directory path (path without filename) in Lua, without loading additional library like LFS, as I'm using Lua extension from other application?
In plain Lua, there is no better way. Lua has nothing working on paths. You'll have to use pattern matching. This is all in the line of the mentality of offering tools to do much, but refusing to include functions that can be replaced with one-liners:
-- onelined version ;)
-- getPath=function(str,sep)sep=sep or'/'return str:match("(.*"..sep..")")end
getPath=function(str,sep)
sep=sep or'/'
return str:match("(.*"..sep..")")
end
x = "/home/user/.local/share/app/some_file"
y = "C:\\Program Files\\app\\some_file"
print(getPath(x))
print(getPath(y,"\\"))
Here is a platform independent and simpler solution based on jpjacobs solution:
function getPath(str)
return str:match("(.*[/\\])")
end
x = "/home/user/.local/share/app/some_file"
y = "C:\\Program Files\\app\\some_file"
print(getPath(x)) -- prints: /home/user/.local/share/app/
print(getPath(y)) -- prints: C:\Program Files\app\
For something like this, you can just write your own code. But there are also libraries in pure Lua that do this, like lua-path or Penlight.

Resources