How to create a DynamoDB entry from F#? - f#

There is the following code on the AWS documentation page (I simplified):
Table table = Table.LoadTable(client, "ProductCatalog");
var book = new Document();
book["Id"] = 101;
book["Title"] = "Book 101 Title";
book["ISBN"] = "11-11-11-11";
table.PutItem(book);
When I try to the same from Fsharp I get an error:
let seqNumberDocument = Document()
seqNumberDocument.["key"] <- 101
Type constraint mismatch. The type
'int' is not compatible with type
'DynamoDBEntry'
Is there a way to get this working in Fsharp?

You'll need to call the implicit conversion to DynamoDBEntry like this:
let seqNumberDocument = Document()
seqNumberDocument.["key"] <- DynamoDBEntry.op_Implicit 101
F# doesn't itself support implicit conversion by design.
If that looks a bit ugly, you can use the alternative:
let v2 = DynamoDBEntryConversion.V2
let seqNumberDocument = Document()
seqNumberDocument.["key"] <- v2.ConvertToEntry 101

Related

XUnit/FsUnit framework throwing "Object reference not set to an instance of an objct"

I have written this simple test case for my code
module CustomerTests
open Xunit
open FsUnit
open MyProject.Customer
open MyProject.Customer.Domain
module ``When upgrading customer`` =
let customerVIP = {Id = 1; IsVip = true; Credit = 0.0M}
let customerSTD = {Id = 2; IsVip = false; Credit = 100.0M}
[<Fact>]
let ``should give VIP customer more credit`` () =
let expected = {customerVIP with Credit = customerVIP.Credit + 100.0M }
let actual = upgradeCustomer customerVIP
actual |> should equal expected
Very surprisingly this code fails with error
[xUnit.net 00:00:00.64] CustomerTests+When upgrading customer.should give VIP cstomer more credit [FAIL]
Failed CustomerTests+When upgrading customer.should give VIP cstomer more credit [3 ms]
Error Message:
System.NullReferenceException : Object reference not set to an instance of an object.
Stack Trace:
at CustomerTests.When upgrading customer.should give VIP cstomer more credit() in /Users/user/code/fsharp/CustomerProject/CustomerTests.fs:line 12
But line 12 is just a record being created so its not possible for that line to throw an Object reference not set to an instance of object. This is totally puzzling me.
In the dotnet fsi repl I can execute all my method and there is no object reference problem in my function which are being called from my tests here.
As this SO answer explains, XUnit loads the test in a way that skips initialization of those values. One easy fix is to use a class instead of a module:
type ``When upgrading customer``() =
let customerVIP = {Id = 1; isVip = true; Credit = 0.0M}
let customerSTD = {Id = 2; isVip = false; Credit = 100.0M}
[<Fact>]
let ``should give VIP cstomer more credit`` () =
let expected = {customerVIP with Credit = customerVIP.Credit + 100.0M }
let actual = upgradeCustomer customerVIP
actual |> should equal expected
That way, initialization of those values happens as it should.

Calling expand entity from SAP Gateway Client

I try to call a GET_EXPANDED_ENTITYSET method of SRA020_PO_TRACKING Project, po tracking project. The following is the method:
METHOD /iwbep/if_mgw_appl_srv_runtime~get_expanded_entityset.
DATA: lv_ponumber TYPE bapiekko-po_number,
lv_leading_msg TYPE boolean.
DATA: lo_api TYPE REF TO cl_sra020_po_tracking_api.
DATA: ls_po_details TYPE cl_sra020_po_tracking_api=>ts_podetails,
lt_return TYPE bapirettab,
lo_msgcontainer TYPE REF TO /iwbep/if_message_container.
DATA: lt_poitem_details TYPE cl_sra020_po_tracking_api=>tt_poitemdetail.
FIELD-SYMBOLS: <fs_return> TYPE bapiret2,
<fs_key_tab> TYPE /iwbep/s_mgw_name_value_pair.
lo_api = cl_sra020_po_tracking_api=>get_instance( ).
*========================================================================================
* Read Entities key values within oData service URL
*========================================================================================
IF it_key_tab IS NOT INITIAL.
LOOP AT it_key_tab ASSIGNING <fs_key_tab>.
CASE <fs_key_tab>-name.
WHEN if_sra020_po_tracking_constant=>cc_po_number.
lv_ponumber = <fs_key_tab>-value.
ENDCASE.
ENDLOOP.
ENDIF.
TRY.
CASE iv_entity_set_name.
WHEN if_sra020_po_tracking_constant=>cc_podetaileddatas.
CALL METHOD lo_api->get_po_details
EXPORTING
iv_item_additional_data = 'X' "#EC NOTEXT
iv_po_number = lv_ponumber
IMPORTING
es_po_details = ls_po_details
et_return = lt_return.
IF NOT lt_return IS INITIAL.
RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception.
ENDIF.
lt_poitem_details = ls_po_details-poitemdetaildatas.
no_cache( ).
* Return the expanded clauses
APPEND cl_sra020_po_tracking_mpc=>gc_poitemdocflow TO et_expanded_tech_clauses.
APPEND cl_sra020_po_tracking_mpc=>gc_accounting TO et_expanded_tech_clauses.
APPEND cl_sra020_po_tracking_mpc=>gc_pricingconditions TO et_expanded_tech_clauses.
APPEND cl_sra020_po_tracking_mpc=>gc_confirmation TO et_expanded_tech_clauses.
CALL METHOD copy_data_to_ref
EXPORTING
is_data = lt_poitem_details
CHANGING
cr_data = er_entityset.
ENDCASE.
CATCH /iwbep/cx_mgw_busi_exception.
lo_msgcontainer = me->mo_context->get_message_container( ).
LOOP AT lt_return ASSIGNING <fs_return> WHERE type EQ 'E' OR type EQ 'A'. "#EC NOTEXT
IF <fs_return>-id EQ 'SRA020'.
lv_leading_msg = abap_true.
ELSE.
lv_leading_msg = abap_false.
ENDIF.
lo_msgcontainer->add_message(
iv_msg_type = <fs_return>-type
iv_msg_id = <fs_return>-id
iv_msg_number = <fs_return>-number
iv_msg_text = <fs_return>-message
iv_msg_v1 = <fs_return>-message_v1
iv_msg_v2 = <fs_return>-message_v2
iv_msg_v3 = <fs_return>-message_v3
iv_msg_v4 = <fs_return>-message_v4
iv_is_leading_message = lv_leading_msg
).
ENDLOOP.
RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
EXPORTING
textid = /iwbep/cx_mgw_busi_exception=>business_error
message_container = lo_msgcontainer.
ENDTRY.
ENDMETHOD.
Where
if_sra020_po_tracking_constant=>cc_po_number = PONumber
if_sra020_po_tracking_constant=>cc_podetaileddatas = PODetailedDatas
and PODetailedData entity has navigation properties of POItemDetailDatas,POItems,and POList
I try to call the method from Gateway Service Client by executing
/sap/opu/odata/SAP/SRA020_PO_TRACKING_SRV/PODetailedDatas?$expand=POItemDetailDatas,POItems,POList
However I got status code 400 Bad Request instead. What did I miss?
regards
Edit:
The message in the Bad Request says: Error while reading Purchase Order
edit 2:
association screen shot:
navigation screen shot:
Turns out I have to provide PONumber, so that:
PODetailedDatas(PONumber='4500000039')?$expand=POItems
works fine

Incomplete structured construct

i am new with f# , will be great if some 1 can help , nearly half a day gone solving this problem Thank you
module Certificate =
type T = {
Id: int
IsECert: bool
IsPrintCert: bool
CertifiedBy: string
Categories: Category.T list
}
let createPending now toZonedDateTime toBeCertifiedByName (job: Models.Job.T) (certificateType: Models.CertificateType.T) (pendingCertificate: Models.PendingCertificate.T) visualization (categories: Category.T list) =
let forCompletion = Models.PendingCertificate.getCertificateForCompletion pendingCertificate
{
Id = forCompletion.Id |> CertificateId.toInt
IsECert = Models.PendingCertificate.isECertificate pendingCertificate
IsPrintCert = Models.PendingCertificate.isPrintCertificate pendingCertificate
CertifiedBy = toBeCertifiedByName
Categories = categories}
i am getting an error in "Incomplete structured construct at or before this point"
Your formatting is all off. I will assume here that this is just a result of posting to StackOverflow, and your actual code is well indented.
The error comes from the definition of createPending: this function does not have a result. All its body consists of defining a forCompletion value, but there is nothing after it. Here's a simpler example that has the same problem:
let f x =
let y = 5
This function will produce the same error, because it also doesn't have a result. In F#, every function has to return something. The body cannot contain only definitions of helper functions or values. For example, I could fix my broken function above like this:
let f x =
let y = 5
x + y
This function first defines a helper value y, then adds it to its argument x, and returns the result.
> f 2
> 7
>
> f 0
> 5
How exactly you need to fix your function depends on what exactly you want it to mean. I can't help you here, because you haven't provided that information.

Error adding containts to solver in z3

assign wfwe = wb_acc & (adr_i == 2'b10) & ack_o & we_i;
For the above assign statement which is in verilog, i getting error while implememting it in z3
My code:
BitVecExpr[] wfwe = new BitVecExpr[1];
BitVecExpr[] wb_acc = new BitVecExpr[1];
BitVecExpr[] adr_i = new BitVecExpr[1];
BitVecExpr[] ack_o = new BitVecExpr[1];
BitVecExpr[] we_i = new BitVecExpr[1];
wfwe[0] = ctx.mkBVConst("wfwe",1);
wb_acc[0] = ctx.mkBVConst("wb_acc",1);
adr_i[0] = ctx.mkBVConst("adr_i",2);
ack_o[0] = ctx.mkBVConst("ack_o",1);
we_i[0] = ctx.mkBVConst("we_i",1);
Solver s = ctx.mkSolver();
s.add(ctx.mkBVAND(wb_acc[0],ctx.mkEq(adr_i[0],ctx.mkNumeral("2",2)),ack_o[0],we_i[0]));
I am getting error in above add statement:
error: method mkBVAND in class Context cannot be applied to given types;
required: BitVecExpr,BitVecExpr
found: BitVecExpr,BoolExpr
Which is true. Can anyone suggest me workaround. Am i implementing it incorrectly please let me know.
This error is reported because the second argument of mkBVAND is a Boolean expression (ctx.mkEq ...). Note that Booleans and BitVectors of size 1 are not the same thing, and they will not be converted automatically. The easiest way to convert between them is an if-then-else the selects the right values.
These are the problems with this example:
1) ctx.mkNumeral("2",2) is incorrect. I guess the intention was to create a bv-numeral of 2 bits with value 2; the easiest way to achieve that is ctx.mkBV(2, 2)
2) The 2nd argument of mkBVAND needs to be converted from Bool to BitVector, e.g., like so:
BoolExpr c = ctx.mkEq(adr_i[0], ctx.mkBV(2, 2));
BitVecExpr e = (BitVecExpr) ctx.mkITE(c, ctx.mkBV(1, 1), ctx.mkBV(0, 1));
e being the result.
3) ctx.mkBVAND takes exactly 2 arguments, no more and no less. Thus, the BVAND expression needs to be rewritten, e.g., like so:
ctx.mkBVAND(ctx.mkBVAND(wb_acc[0], e), ctx.mkBVAND(ack_o[0], we_i[0])))
4) The result needs to be converted to a Boolean expression again, e.g.
ctx.mkEq(q, ctx.mkBV(1, 1))
where q is the result of the BVAND.

F# Excel Range.AutoFilter() fails

I'm trying to turn on AutoFilter for the users who will consume the data.
open Microsoft.Office.Interop.Excel
let xl = ApplicationClass()
xl.Workbooks.OpenText(fileName...)
let wb = xl.Workbooks.Item(1)
let ws = wb.ActiveSheet :?> Worksheet
let rows = string ws.UsedRange.Rows.Count
// AutoFilter method of Range class failed.
ws.Range("A7:I" + rows).AutoFilter() |> ignore
Thanks for any help you can offer.
According to the documentation, you need to pass 5 parameters to AutoFilter.
Unspecified parameters can be filled by System.Reflection.Missing.Value.
Something like
ws.Range("A7:I" + rows).AutoFilter(1, System.Reflection.Missing.Value,
Excel.XlAutoFilterOperator.xlAnd,
System.Reflection.Missing.Value, true)
|> ignore
should work.

Resources