F#代码——天气预报
这个是很早很早之前作的一个小东西,不过由于工作时间原因,没能做好,留个笔记:
// Learn more about F# at http://fsharp.net //namespace WeatherDemo #if INTERACTIVE #r @"C:\Program Files\Reference Assemblies\Microsoft\FSharp\3.0\Runtime\v4.0\Type Providers\FSharp.Data.TypeProviders.dll" #r @"C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Profile\Client\System.ServiceModel.dll" #r "System.XML.Linq.dll" #r "System.Xml.dll" #endif open Microsoft.FSharp.Data.TypeProviders open System.ServiceModel open System.Xml.Linq open System.ServiceModel.Channels open System.ServiceModel.Dispatcher open System open System.Text open System.Xml open System.Xml.Serialization open System.IO open System.Collections.Generic type TPmap = Microsoft.FSharp.Data.TypeProviders.WsdlService<ServiceUri = "http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl"> type port = TPmap.ServiceTypes.ndfdXMLPortType type GetWeather() = //Bug : 260425 [DotCompletion]Dotcompletion doesn't work for the code after keyword inherit //inherit Microsoft //Bug : 265164 [DotCompletion]Incompleted completionlist showed while going back to get the list using shortkey let client = new TPmap.ServiceTypes.ndfdXMLPortTypeClient() // A bounch of default argument let m_timeSeries = TPmap.ServiceTypes.productType.timeseries let m_ss = TPmap.ServiceTypes.productType() let m_startTime = System.DateTime.Now let m_endTime = System.DateTime.Now.AddDays(1.0) let m_weatherParam = new TPmap.ServiceTypes.weatherParametersType() let m_product = new TPmap.ServiceTypes.productType() let m_SetDefaultArg = m_weatherParam.maxt <- true m_weatherParam.mint <- true m_weatherParam.temp <- true m_weatherParam.sky <- true m_weatherParam.appt <- true m_weatherParam.conhazo <- true m_weatherParam.dew <- true m_weatherParam.icons <- true // Parse data from the XML String which retured by NWS . let ParseSpecifyNodeFromXMLString(srcData : string, specifiedNode : string) = let xName = XName.Get(specifiedNode) //Get all the children Elements of root . Transfer the Seq to List let childToList = srcData |> XDocument.Parse |> fun xDoc -> xDoc.Root |> fun rootElement -> rootElement.Elements() |> Seq.toList // Define a specific transfer function , used in the rec function. let seqTolist (srcElement : XElement) = let childElementsList = srcElement |> fun x -> x.Elements() |> fun xSeq -> (xSeq |> Seq.toList) childElementsList //Used to store the result in for loop let (resultList : list<XElement> ref) = ref [] //Rec function used to get the specific XElement by given XName let rec selecteElement (dataList : list<XElement>) = for element in dataList do if (element.HasElements = true) then match element with | _ when element.Name = xName -> resultList := List.append ([element]) !resultList printfn "" | _ -> element |> seqTolist |> selecteElement selecteElement childToList !resultList // This funciton is used to convert the string to ISO-8895-1 let convertStrToIso (str : string) = // BUgs here let ``Unicode`` = System.Text.Encoding.Unicode let unicodeBytes = ``Unicode``.GetBytes(str) let unicodeStr = ``Unicode``.GetString(unicodeBytes) let ``iso-8859-1`` = System.Text.Encoding.GetEncoding("iso-8859-1") let isoBytes = ``iso-8859-1``.GetBytes(str) let isoStr = ``iso-8859-1``.GetString(isoBytes) isoStr //let resultBytes = System.Text.Encoding.Convert(``Unicode``,``iso-8859-1``,unicodeBytes) //Bug : While followed by lots of code , the parameterInfo will not work here //System.Text.Encoding.GetEncoding("iso-8859-1").GetString(isoStr) //Pass the XElement which contain the infomation of what we what and parse it . For instance , I want get temperature info , //so I pass the XElement list which contain information of temp, then I use name to get the name of this node ,use value to get value of temp. let scrabResultOfExpected (queryXElementResult : list<XElement>) (name : string) (value : string) = let nameOfNode = queryXElementResult |> fun xElement -> xElement.[0] |> fun valueOfElement -> valueOfElement.Element(XName.Get(name)).Value let vauleOfNodes = queryXElementResult |> fun xElement -> xElement.[0] |> fun valueOfElement -> valueOfElement.Elements(XName.Get(value)) |> Seq.toList |> List.map (fun item -> item.Value) let result = [nameOfNode] @ vauleOfNodes result // Used to explicit invoke the open Method to avoid reopen the client . member this.OpenClient() = client.Open() //Used to explicit invoke the close Method member this.CloseClient() = client.Close() //Bug: C# can't consume the method which defined in F# with default argument. //Bug ? : 268097 Make comments just close to "=" failed member this.GetTemperatureInfoAtSpecifyPointByNDFDgen(lat : System.Decimal, lon : System.Decimal , index : int) = //, ?timeSeries : TPmap.ServiceTypes.productType, ?startTime : System.DateTime, ?endTime : System.DateTime, ?weatherParam : TPmap.ServiceTypes.weatherParametersType) = try //client.Open() m_SetDefaultArg let data = client.NDFDgen(lat, lon, m_timeSeries,m_startTime, m_endTime, m_weatherParam) data |> XDocument.Parse |> fun doc -> doc.Save(@"C:\Users\v-shuzhu\Desktop\Output.xml") //Parse the temperature data from the returned XML string. let parsedResult = ParseSpecifyNodeFromXMLString(data,"temperature") //Query the XElement of temperature let queryTempValue (condition : string) = query{ for xElement in parsedResult do where(xElement.Attribute(XName.Get("type")).Value = condition) //Bug : 262064 [Query][Debug]Can't select whole line code while setting breakpoint in query select xElement } |> Seq.toList // Used to provide different items for customers. Including Max,Min and Hourly temperature info. let getValueOfTempXElement (index : int) = let condition = match index with | 1 -> "maximum" | 2 -> "minimum" | 3 -> "hourly" | _ -> "Out of index" scrabResultOfExpected (queryTempValue(condition)) "name" "value" (getValueOfTempXElement index) //|> List.iter( fun x -> printfn "%s" x) with | excn -> ["Here Error"] member this.GetCloudInSkyInfoAtSpecifyPointByNDFDgen(lat : System.Decimal, lon : System.Decimal) = try //client.Open() m_SetDefaultArg let data = client.NDFDgen(lat, lon, m_timeSeries,m_startTime, m_endTime, m_weatherParam) data |> XDocument.Parse |> fun doc -> doc.Save(@"C:\Users\v-shuzhu\Desktop\Output.xml") let parsedResult = ParseSpecifyNodeFromXMLString(data,"cloud-amount") let queryResult = query{ for xElement in parsedResult do select xElement } |> Seq.toList (scrabResultOfExpected queryResult "name" "value") with | extn -> ["Error"] //Not implemented yet member this.GetSupportedCityNames() = try let requestStr = "<soapenv:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:ndf='http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl' xmlns:dwml='http://www.weather.gov/forecasts/xml/DWMLgen/schema/DWML.xsd'> <soapenv:Header/> <soapenv:Body> <ndf:LatLonListCityNames soapenv:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'> <displayLevel xsi:type='dwml:displayLevelType'>1</displayLevel> </ndf:LatLonListCityNames> </soapenv:Body> </soapenv:Envelope> " //client.Open() //client.DisplayInitializationUI() try // ??? Can not get the XML string... // Bug here : ParameterInfo doesn't work here. let result = client.LatLonListCityNames(convertStrToIso(requestStr)) result |> XDocument.Parse |> fun doc -> doc.Save(@"C:\Users\v-shuzhu\Desktop\Output.xml") with | _ -> printfn "Null" with | excn -> printfn "Get Nothing" //For instance : we can get those cities which fit for trival. member this.QueryCitiesWithSpecifiedTemp( condition : string, wholeCitiesDicList : list<System.Collections.DictionaryEntry>) = let roundTemp = [ [90;113]; [64;90]; [32;64]; [0;32] ] let tempKey = [ "hot"; "comfortable"; "cold"; "frozen" ] let initConditionDicList = ref [] for i in 0..3 do initConditionDicList := (!initConditionDicList @ [new System.Collections.DictionaryEntry(tempKey.[i],roundTemp.[i])]) let tempCondition = query{ for temp in !initConditionDicList do where ((temp.Key :?> string) = condition) select temp.Value } |> Seq.toList |> fun x -> x.[0] let tempCondition = tempCondition :?> list<int> let getWholeCitiesTempDicList = let resultList = ref [] for i in wholeCitiesDicList do let value = (i.Value) :?> (Decimal * Decimal) let maxTemp = (int)(this.GetTemperatureInfoAtSpecifyPointByNDFDgen( (fst value), (snd value), 1 ).[0]) let minTemp = (int)(this.GetTemperatureInfoAtSpecifyPointByNDFDgen( (fst value), (snd value), 2 ).[0]) if(minTemp > (tempCondition.[0]) && (maxTemp < tempCondition.[1])) then resultList := !resultList @ [new System.Collections.DictionaryEntry(i.Key,(minTemp,maxTemp))] !resultList getWholeCitiesTempDicList member this.GetIconLink(lat, lon) = try //client.Open() m_SetDefaultArg let data = client.NDFDgen(lat, lon, m_timeSeries,m_startTime, m_endTime, m_weatherParam) data |> XDocument.Parse |> fun doc -> doc.Save(@"C:\Users\v-shuzhu\Desktop\Output.xml") let parsedResult = ParseSpecifyNodeFromXMLString(data,"conditions-icon") scrabResultOfExpected parsedResult "name" "icon-link" //|> List.iter (fun x -> printfn "%s" x) with | _ -> ["Icon Error"] let test = new GetWeather() test.OpenClient() test.GetCloudInSkyInfoAtSpecifyPointByNDFDgen(39.0000M,-77.0000M) |> List.iter (fun x -> printfn "%s" x) ////let time = new System.Timers.Timer(20000.0) ////time.Start() test.GetTemperatureInfoAtSpecifyPointByNDFDgen(39.0000M,-77.0000M, 3) |> List.iter (fun x -> printfn "%s" x) test.GetSupportedCityNames() //|> printfn "%s" //test.GetIconLink(39.0000M,-77.0000M) test.GetIconLink(39.0000M,-77.0000M) |> List.iter (fun x -> printfn "%s" x) test.CloseClient()
这个还不够完善,不过还是要做个笔记比较好~ :)