Dictionary doesn't return value for key that is present - powershell-2.0

I built a dictionary that I am trying to use in a script I'm building, but when I try to use the key to access a value from it, I am getting no response.
$dictionary = [System.Collections.Generic.Dictionary[string,int[]]]::new()
foreach($obj in $Object){
$formattedName = $obj.'Format'
if(-not$($dictionary.ContainsKey($formattedName))){
$Total= [int32]::Parse($obj.'Total')
$charCount = $formattedName.length
$intArray = #($Total,$charCount)
$dictionary.Add($formattedName,$intArray)
}
}
When I check the dictionary I do get a filled object as expected:
Key Value
A1 {1,2}
A2 {1,2}
A3456 {3,5}
But, when I try to access this dictionary by keys to get the corresponding values, I get no response from the console:
$dictionary[A1]
$dictionary["A1"]
$dictionary["$($dictionary.keys[0])"]
returns: nothing instead of {1,2}
Trying to figure out where I am misunderstanding... When I check the member of $dictionary I get
System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089],[System.Int32[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]

Solved by including an output type for the function that was returning the dictionary
[OutputType([System.Collections.Generic.Dictionary[string,int[]]])]
I think the object the function I was calling to build the dictionary was returning an custom object instead of a generic dictionary.

Related

Why jsonDecode in Dart has no type and no documentation?

As you can see in https://api.dart.dev/stable/2.7.1/dart-convert/jsonDecode.html, it has no type and no documentation. I don't know which methods I can invoke on the result neither I don't know which type to but on a parameter that should be a json object.
Why is Dart like this? And what are the advantages?
It does have documentation, and you are linking to it.
If you want it to have more documentation, then that is reasonable. The returned value is admittedly not documented very well.
The function jsonDecode is a shorthand for json.decode, which again forwards to JsonDecoder.convert.
It returns a "JSON value" object which depends on the JSON source that it decodes.
A "JSON value" can be any of:
* null
* an int
* a double
* a String
* a bool (true or false)
* a List<dynamic> containing zero or more JSON values.
* a Map<String, dynamic> mapping keys to JSON values.
Those are also the same values that are accepted by the JsonEncoder which converts object structures to JSON strings.
Since these types have no common superclass other than Object, the function cannot have a return type which is more specific than dynamic or Object.
The chosen return type is dynamic because the dynamic type allows the receiver to optimistically call any member on the value. They might know that the value will always be a map, so they can just do jsonParse(jsonSource)["key"] to look up a value. Obviously, if the source was not a JSON object, that call will fail.
If you don't know which type the result is, you have to check:
var data = jsonDecode(jsonSource);
if (data is Map<String, dynamic>) {
something something data["key"] something
} else if (data is List<dynamic>) {
something something list[2] something
} else ... etc ...
A valid JSON file is actually a valid Dart expression too. The value returned by jsonDecode is similar to the value you would get if you wrote the JSON code directly as Dart code (in Dart 1 it was exactly the same, in Dart 2, the Dart code might infer a more precise type for maps and lists).

Get string value out of a KeySym value

Is there a way to get the string value out of a KeySym value?
For example, out of keyPrintable("a").
If you know the KeySym value is a keyPrintable, you can just get it using the key property. For instance
KeySym kv = ... // something that yields a KeySym
str s = kv.key;
If you don't know it's a keyPrintable you can either check to see if it was built using that constructor, or use pattern matching. So, either
if (kv is keyPrintable) {
// code that uses kv.key to get back the value
}
or
if (keyPrintable(str s) := kv) {
// code that can now use s, which is the key
}
You can also ask if kv has that field, and then use it:
if (kv has key) {
// code that uses kv.key
}
Once you introduce a field name in a constructor, and it has a specific type, you know that same field name has that same type in any additional constructors for the same datatype. So, once we know field key is type str, field key has to be str in any value of type KeySym. That is why it's fine to see if kv has field key and then treat it as a str, nobody could come along later and add a new constructor for KeySym where key has a different type.

Extract case-insensitive query parameter from URL

I am trying to extract the case-insensitive query parameter /staging/ec/23463/front-view-72768.jpg?angle=90&or=0x0&wd=400&ht=200 from the URL. When I try to convert the whole URL in lowercase it throws the following exception :
cannot use r.URL (type *url.URL) as type string in argument to strings.ToLower
I printed the value of URL which says underlying it stores all the query strings as map i.e. map[angle:[90] or:[0x0] wd:[400] ht:[200]]. Hence I will get the correct value using this r.URL.Query().Get("or") But if query string comes out Or. It will fail.
*URL.Query() returns a value of type url.Values, which is just a map[string][]string with a few extra methods.
Since URL values are by definition case-sensitive, you will have to access the map directly.
var query url.Values
for k, vs := range query {
if strings.ToLower(k) == "ok" {
// do something with vs
}
}
Try it on the playground: https://play.golang.org/p/7YVuxI3GO6X
cannot use r.URL (type *url.URL) as type string in argument to strings.ToLower
This is because you are passing ur.URL instead of string. Get the string from url through String() function.
url.String()

KendoUI Grid inline editor DefaultValue bug

I have a KendoGrid with inline editing functionality. Problem is, upon rendering, the grid throws an error while binding a nullable decimal datatype in DefaultValue property.
I use this code to bind DefaultValue.
decimal? val = 0M; //nullable decimal
model.Field(columnSetting.Member, memberType).DefaultValue(val);
Here's the error:
Invalid cast from 'System.Decimal' to
'System.Nullable`1[[System.Decimal, mscorlib, Version=4.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089]]'.
My model has a nullable decimal datatype in it so the grid should expect the same datatype. But still, it throws this error. Is this a KendoGrid bug? Or am I missing something?
Any help would be appreciated. Thanks!

F# type provider - "only return generated types"

Trying to encode type-level peano numbers using a type provider:
namespace TypeProviderPlayground
open System
open Microsoft.FSharp.Core.CompilerServices
open System.Runtime.CompilerServices
[<assembly: TypeProviderAssembly()>]
do()
type Z = class end
type 'a S = class end
type N = class end
[<TypeProvider>]
type PeanoProvider(s: TypeProviderConfig) =
let invalidate = Event<_,_>()
interface ITypeProvider with
member x.ApplyStaticArguments(typeWithoutArguments, typeNameWithArguments, staticArguments) =
let n : int = unbox staticArguments.[0]
[1..n] |> List.fold (fun s _ -> typedefof<S<_>>.MakeGenericType [| s |]) typeof<Z>
member x.GetNamespaces() =
let ns =
{ new IProvidedNamespace with
member x.GetNestedNamespaces() = [||]
member x.GetTypes() = [||]
member x.ResolveTypeName t =
if t = "N"
then typeof<N>
else null
member x.NamespaceName = "Peano" }
[| ns |]
member x.GetStaticParameters t =
let p =
{ new Reflection.ParameterInfo() with
member z.Name = "number"
member z.ParameterType = typeof<int> }
[| p |]
[<CLIEvent>]
member x.Invalidate = invalidate.Publish
member x.Dispose() = ()
member x.GetInvokerExpression(syntheticMethodBase, parameters) =
raise <| NotImplementedException()
The N type is just a dummy, otherwise I couldn't get it to go through the type provider.
Consumer code:
open TypeProviderPlayground
[<Generate>]
type S<'a> = Peano.N<5>
And I get this error:
error FS3152: The provider 'TypeProviderPlayground.PeanoProvider' returned a non-generated type
'TypeProviderPlayground.S`1[[TypeProviderPlayground.S`1[[TypeProviderPlayground.S`1[[TypeProviderPlayground.S`1[[TypeProviderPlayground.S`1[[TypeProviderPlayground.Z, TypeProviderPlayground, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]], TypeProviderPlayground, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]], TypeProviderPlayground, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]], TypeProviderPlayground, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]], TypeProviderPlayground, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]'
in the context of a [<Generate>] declaration. Either remove the [<Generate>] declaration or adjust the type provider to only return generated types.
Which says that the type was correctly constructed (Z S S S S S) but for some reason the compiler won't accept it as a "generated type".
If I remove the [<Generated>] attribute I get some other error telling me to add it.
Does this mean that type providers will only work on dynamically emitted types (which seems a weird requirement at first blush)?
Also, if I do:
[<Generate>]
type WW<'a> = Peano.N<5>
I get an error saying that WW'1 was expected but S'1 was returned. Why does the returned type (by the type provider) have to match the type name I declare in the consumer?
There are a few important things to realize about type providers. First of all, there are two kinds of provided types:
Generated types are real .NET types that get embedded into the assembly that uses the type provider (this is what the type providers that wrap code generation tools like sqlmetal use)
Erased types are simulated types which are represented by some other type when the code is compiled.
Just as a heads-up, the mechanisms for controlling this distinction are still somewhat up in the air. In the preview, you need to use the [<Generate>] attribute in the assembly into which generated types are being embedded, and you should not use the [<Generate>] attribute when using an erased provided type. I believe (but can't remember for sure off hand) that on the provided end generated-ness is determined based on the type's Assembly property.
Also, keep in mind that you don't necessarily want to use actual types (e.g. via typeof<X>) when implementing the API - you'll frequently want to use custom types derived from System.Type. There are a lot of invariants that must be satisfied among the different methods. The raw type provider API is not easy to use - I'd suggest waiting for some examples to be released which use a nicer API wrapper (which I hope should take place within the next few weeks).
Having said that, from a quick look here are at least a few things in your current approach which look wrong to me:
The type that you're returning from ApplyStaticArguments doesn't have the same name as the argument typeNameWithArguments. Presumably this is why you're getting the error mentioning the type names.
You're trying to use a type abbreviation which creates a generic type (e.g. WW<'a>) from a non-generic type (e.g. S<S<S<S<S<Z>>>>>).
Forgot to update on this: indeed what was missing was the 'erased' type flag (TypeProviderTypeAttributes.IsErased) in my 'exported' type. I put my experiments on github.

Resources