โŒ About FreshRSS

Normal view

There are new articles available, click to refresh the page.
Before yesterdayNews from the Ada programming language world

Recursion โ€“ Compound Interest (in Ada)

By: spqr
6 March 2023 at 15:28

It might seem odd to think of a compound interest as a problem which could be solved by recursion, but it does make sense. The algorithm for calculating compound interest is of course very simple:

interest = current_balance ร— interest_rate
new_balance = current_balance + interest
current_balance = new_balance

Of course this calculation is done numerous times depending on how many times the interest is to be compounded. If we were to write a simple function in Ada it would look like this:

with text_io; use text_io;
with ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with ada.Float_Text_IO; use Ada.Float_Text_IO;

procedure compound is
   newBal, currBal, intRate, monRate : float;
   numMon : natural;

   function compound_interest(bal: float; intr: float; n: natural) return float is
      interest: float;
      newbal: float := bal;
   begin
      for i in 1..n loop
         interest := newbal * intr;
         newbal := newbal + interest;
      end loop;
      return newbal;
   end compound_interest;

begin
   put("Balance ($)? "); new_line;
   get(currBal); skip_line;
   put("Interest rate (e.g. 5.3)? "); new_line;
   get(intRate); skip_line;
   put("Number of months (1-12)? "); new_line;
   get(numMon); skip_line;

   monRate := intRate / 100.0 / 12.0;
   newBal := compound_interest(currBal,monrate,numMon);
   put("The new balance is $");
   put(newBal, 1, 2, 0);
end compound;

Here is the program running:

Balance ($)?
1000
Interest rate (e.g. 5.3)?
5
Number of months (1-12)?
12
The new balance is $1051.16

This nonrecursive procedure is fine, but we can also solve it recursively. If we say that the balance, b, after 0 months is the amount of the original deposit, d, and the interest rate is r, then we can write:

At month 0: b(0) = d
At month 1 : b(1) = b(0) + b(0) * r
At month 2 : b(2) = b(1) + b(1) * r
...

Then we can form a recursive definition of the form:

b(m) = b(m-1) + b(m-1) * r

Therefore we can use this to create a recursive function:

b(0) = d
b(m) = b(m-1) + b(m-1) * r

Here is a recursive version of the function compound_interest().

function compound_interestR(bal: float; intr: float; n: natural) return float is
   newbal: float;
begin
   if n = 0 then
      return bal;
   elsif n = 1 then      
      return bal + bal * intr;
   else
      newbal := compound_interestR(bal,intr,n-1);
      return newbal + newbal * intr;
   end if;
end compound_interestR;

AWA 2.4.0

7 August 2022 at 21:12

The framework provides several ready to use and extendable modules that are common to many web applications. This includes the login, authentication, users, permissions, managing comments, tags, votes, documents, images. It provides a complete blog, question and answers and a wiki module.

AWA simplifies the Web Application development by taking care of user management authentication and by providing the foundations on top of which you can construct your own application. AWA provides a powerful permission management that gives flexibility to applications to grant access and protect your user's resources.

A typical architecture of an AWA application is represented by the picture below:

[Ada Web Application architecture](Ada/awa_architecture_overview.png)
    1. Using AWA with Alire

To use AWA with Alire, you should first register a new index to get access to the AWA crates and its dependencies.

``` alr index add git+https://github.com/stcarrez/awa-alire-index name awa ```

After this command, the `alr` command should give you access to the AWA crates and you can check that with the command:

``` alr search awa ```

Once you have setup the Alire index, you can import the `awa` framework and the `dynamo` associated tool by using the following commands:

``` alr init demo cd demo alr with awa alr with dynamo alr with servletada_aws alr build ```

Note, if you are using FreeBSD, you should probably use the following command to build (because the MariaDB shared libraries are installed in `/usr/local/lib/mariadb` directory):

``` alr build -- -largs -L/usr/local/lib/mariadb ```

Once the `dynamo` tool is built, you can use it to setup your project by using the `create-project` command. To run the `dynamo` tool, you must run it by using the `alr exec` command because Alire will setup some environment variables and `PATH` that gives access to Dynamo and AWA configuration files.

``` alr exec dynamo create-project -l apache web demo [email protected] ```

Change the `demo.gpr` GNAT project that was generated by `alr` and replace `demo.adb` by `demo-server.adb`. That later source has been generated by `dynamo` and it contains everything to setup, prepare and run the Web server. Once this is done, build the application:

``` alr build ```

The Atlas AWA Demonstrator(https://github.com/stcarrez/atlas) is also available as Alire crates. Two versions are available, the `atlas` crate is using the Ada Web Server and the `atlas_ews` is using the Embedded Web Server. To play to Atlas, you can try one of the following commands:

``` alr get atlas

  1. or

alr get altas_ews ```

    1. Debian packages

Debian packages are also available for Ubuntu 20, Ubuntu 22 and Debian 11. The repository also includes a Debian package for Alire 1.2. Choose **one** of the following configuration and add it to your `/etc/apt/sources.list` configuration.

``` deb https://apt.vacs.fr/ubuntu-focal focal main

  1. or

deb https://apt.vacs.fr/ubuntu-jammy jammy main

  1. or

deb https://apt.vacs.fr/debian-bullseye bullseye main ```

And you can run the following command to accept the signed packages:

``` wget -O - https://apt.vacs.fr/apt.vacs.fr.gpg.key | sudo apt-key add - ```

      1. AWA 2.4.0(https://github.com/stcarrez/ada-awa/releases/tag/2.4.0) Download: awa-2.4.0.tar.gz(http://download.vacs.fr/ada-awa/awa-all-2.4.0.tar.gz)
 - Add support for SQL queries embedded in applications with ARE
 - Fix #20: Do not use git:// protocol
 - New EasyMDE plugin to integrate the Easy Markdown Editor
 - Update AWA blog and AWA wiki to use the EasyMDE editor for Markdown
 - Use Dynamo 1.3.0, Ada Server Faces 1.5.0, Ada Servlet 1.6.0, OpenAPI Ada 0.6.0
 - Use Ada Wiki 1.4.0, Ada Database Objects 2.3.0
 - Use Ada Keystore 1.3.3, Ada EL 1.8.5, Ada Utility Library 2.5.0
      1. Dynamo 1.3.0(https://github.com/stcarrez/dynamo/releases/tag/1.3.0) Download: dynamo-1.3.0.tar.gz(http://download.vacs.fr/dynamo/dynamo-1.3.0.tar.gz)
 - Fix #5: Generated body does not compile when an enumeration of another UML package is used
 - Fix #7: No default type for SQL generation of a column that uses an enumeration
 - Fix #9: Option or configuration to disable some SQL generation
 - Fix #10: Definition of an UML datatype with a tagged value raises an exception
 - Fix #12: Avoid emitting a full qualified type name for types declared in the current package
 - Fix #16: Improvement in Markdown documentation generator
 - Fix #17: YAML parser: accessibility check failure
 - Fix #18: Generate database operation to reload an object
 - Fix #19: Add dynamo configuration through environment support
 - Fix #20: Give access to the man page from alire
 - Fix $21: Generated procedure Create is missing overriding keyword
      1. OpenAPI Ada 0.6.0(https://github.com/stcarrez/swagger-ada/releases/tag/0.6.0) Download: openapi-ada-0.6.0.tar.gz(http://download.vacs.fr/openapi-ada/openapi-ada-0.6.0.tar.gz)
 - Rename Swagger package into OpenAPI and provide a Swagger package for compatibility
 - Update the openapi generator to version 6.0.0
 - Add support for text/plain response
 - Add support to use external Ada types in OpenAPI definitions
 - Add support for multiple response types
 - Add support for binary responses
 - Add support for Ada enum generation for OpenAPI enums
 - Integrate Swagger UI v4.13.0
      1. Ada Server Faces 1.5.0(https://github.com/stcarrez/ada-asf/releases/tag/1.5.0) Download: ada-asf-1.5.0.tar.gz(http://download.vacs.fr/ada-asf/ada-asf-1.5.0.tar.gz)

- New widget <w:progress> to display horizontal/vertical progress bars

      1. Ada Servlet 1.6.0(https://github.com/stcarrez/ada-servlet/releases/tag/1.6.0) Download: ada-servlet-1.6.0.tar.gz(http://download.vacs.fr/ada-servlet/ada-servlet-1.6.0.tar.gz)
      2.  - Fix #4: Alire servletada_aws GNAT project fails due to missing Naming rule
         - Fix #5: The Input_Line_Size_Limit parameter is not taken into account
         - Fix #6: GNAT configuration project is not correct to build with debugging
         - Fix #7: Constraint error raised when matching empty path routes
         - Fix #11: Support for Embedded Web Server
         - Fix #12: Support for multiple response types in REST operations
        
      1. Ada Security 1.4.1(https://github.com/stcarrez/ada-security/releases/tag/1.4.1) Download: ada-security-1.4.1.tar.gz(http://download.vacs.fr/ada-security/ada-security-1.4.1.tar.gz)
 - Fix Alire GNAT project to build in debug mode
 - Fix Security.Random that generates shorter random string
      1. Ada Database Objects 2.3.0(https://github.com/stcarrez/ada-ado/releases/tag/2.3.0) Download: ada-ado-2.3.0.tar.gz(http://download.vacs.fr/ada-ado/ada-ado-2.3.0.tar.gz)
 - Fix #4: Is_Loaded predicate operation is false when an object is not yet inserted in the database
 - Fix #5: Exception raised when SQLite Query_Statement is finalized if the SQL query was invalid
 - Fix #7: Update SQLite support to 3.31.1
 - Fix #8: Add SQlite busy handler to handle the SQLITE_BUSY error
 - Fix #9: Better handling of SQLITE_BUSY error
 - Fix #10: Error 'XML query file does not exist' when the query is loaded from a static embedded loader
      1. Ada Wiki Engine 1.5.0(https://github.com/stcarrez/ada-wiki/releases/tag/1.5.0) Download: ada-wiki-1.5.0.tar.gz(http://download.vacs.fr/ada-wiki/ada-wiki-1.5.0.tar.gz)
      2.  - Add support for Textile markup language
         - Rewrote the Markdown parser to better follow the Common Mark Specification
        
      1. Ada Utility Library 2.5.0(https://github.com/stcarrez/ada-util/releases/tag/2.5.0) Download: ada-util-2.5.0.tar.gz(http://download.vacs.fr/ada-util/ada-util-2.5.0.tar.gz)
 - New examples to illustrate the IO stream composition
 - New examples for JSON parser and Util.Beans.Objects
 - Add support to set environment variables when launching a process (without changing the current process environment!)
 - Add support to indent XML output streams
 - New package Util.Files.Rolling to provide a rolling file manager
 - New package Util.Beans.Objects.Iterators to easily iterate over objects
 - Add a new log appender to support rolling log files with size and time based policies
 - New operation Util.Files.Delete_Tree to delete a directory tree and work arround
   for GNAT bug gcc/63222 and gcc/56055
 - New operation Util.Files.Realpath to find the canonicalized absolute path of a file
 - New package Util.Blobs to hold binary content with reference counting
 - New package Util.Http.Headers to provide some HTTP helper operations
 - Add support for Blob in bean objects
 - Fix compilation on NetBSD 9.2
 - Fix compilation with AWS >= 22.0

Generating a REST Ada client with OpenAPI and Swagger Codegen

8 October 2017 at 18:32

swagger-ada-generator.png

Writing an OpenAPI document

The OpenAPI document is either a JSON or a YAML file that describes the REST API operations. The document can be used both for the documentation of the API and for the code generation in several programming language. We will see briefly through the Petstore example how the OpenAPI document is organized. The full OpenAPI document is available in petstore.yaml.

General description

A first part of the OpenAPI document provides a general description of the API. This includes the general description, the terms of service, the license and some contact information.

swagger: '2.0'
info:
  description: 'This is a sample server Petstore server.  You can find out more about Swagger at [http://swagger.io](http://s
wagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/).  For this sample, you can use the api key `special-key
` to test the authorization filters.'
  version: 1.0.0
  title: Swagger Petstore
  termsOfService: 'http://swagger.io/terms/'
  contact:
    email: [email protected]
  license:
    name: Apache 2.0
    url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
host: petstore.swagger.io
basePath: /v2

Type description

The OpenAPI document can also describe types which are used by the REST operations. These types provide a description of how the data is organized and passed through the API operations.

It is possible to describe almost all possible types from simple properties, group of properties up to complex types including arrays. For example a Pet type is made of several properties each of them having a name, a type and other information to describe how the type is serialized.

definitions:
  Pet:
    title: a Pet
    description: A pet for sale in the pet store
    type: object
    required:
      - name
      - photoUrls
    properties:
      id:
        type: integer
        format: int64
      category:
        $ref: '#/definitions/Category'
      name:
        type: string
        example: doggie
      photoUrls:
        type: array
        xml:
          name: photoUrl
          wrapped: true
        items:
          type: string
      tags:
        type: array
        xml:
          name: tag
          wrapped: true
        items:
          $ref: '#/definitions/Tag'
      status:
        type: string
        description: pet status in the store
        enum:
          - available
          - pending
          - sold
    xml:
      name: Pet

In this example, the Pet type contains 6 properties (id, category, name, photoUrls, tags, status) and refers to two other types Category and Tag.

Operation description

Operations are introduced by the paths object in the OpenAPI document. This section describes the possible paths that can be used by URL and the associated operation. Some operations receive their parameter within the path and this is represented by the {name} notation.

The operation description indicates the HTTP method that is used get, post, put or delete.

The following definition describes the getPetById operation.

paths:
  '/pet/{petId}':
    get:
      tags:
        - pet
      summary: Find pet by ID
      description: Returns a single pet
      operationId: getPetById
      produces:
        - application/xml
        - application/json
      parameters:
        - name: petId
          in: path
          description: ID of pet to return
          required: true
          type: integer
          format: int64
      responses:
        '200':
          description: successful operation
          schema:
            $ref: '#/definitions/Pet'
        '400':
          description: Invalid ID supplied
        '404':
          description: Pet not found
      security:
        - api_key: []

The summary and description are used for the documentation purposes. The operationId is used by code generators to provide an operation name that a target programming language can use. The produces section indicates the media types that are supported by the operation and which are generated for the response. The parameters section represents all the operation parameters. Some parameters can be extracted from the path (which is the case for the petId parameter) and some others can be passed as query parameter.

The responses section describes the possible responses for the operation as well as the format used by the response. In this example, the operation returns an object described by the Pet type.

Using Swagger Codegen

The documentation and the Ada client are generated from the OpenAPI document by using the Swagger Codegen generator. The generator is a Java program that is packaged within a jar file. It must be launched by the Java 7 or Java 8 runtime.

Generating the documentation

The HTML documentation is generated from the OpenAPI document by using the following command:

 java -jar swagger-codegen-cli.jar generate -l html -i petstore.yaml -o doc

Generating the Ada client

To generate the Ada client, you will use the -l ada option to use the Ada code generator. The OpenAPI document is passed with the -i option.

 java -jar swagger-codegen-cli.jar generate -l ada -i petstore.yaml -o client \
       -DprojectName=Petstore --model-package Samples.Petstore

The Ada generator uses two options to control the generation. The -DprojectName=Petstore option allows to control the name of the generated GNAT project and the --model-package option controls the name of the Ada package for the generated code.

The Ada generator will create the following Ada packages:

  • Samples.Petstore.Models is the package that contains all the types described in the OpenAPI document. Each OpenAPI type is represented by an Ada record and it

is also completed by an instantiation of the Ada.Containers.Vectors package for the representation of arrays of the given type. The Models package also provides Serialize and Deserialize procedures for the serialization and deserialization of the data over JSON or XML streams.

  • Samples.Petstore.Clients is the package that declares the Client_Type tagged record which provides all the operations for the OpenAPI document.

For the Pet type describe previously, the Ada generator produces the following code extract:

package Samples.Petstore.Models is
   ...
   type Pet_Type is
     record
       Id : Swagger.Long;
       Category : Samples.Petstore.Models.Category_Type;
       Name : Swagger.UString;
       Photo_Urls : Swagger.UString_Vectors.Vector;
       Tags : Samples.Petstore.Models.Tag_Type_Vectors.Vector;
       Status : Swagger.UString;
     end record;
     ...
end Samples.Petstore.Models;

and for the operation it generates the following code:

package Samples.Petstore.Clients is
   ...
   type Client_Type is new Swagger.Clients.Client_Type with null record;
   procedure Get_Pet_By_Id
      (Client : in out Client_Type;
       Pet_Id : in Swagger.Long;
       Result : out Samples.Petstore.Models.Pet_Type);
   ...
end Samples.Petstore.Clients;

Using the REST Ada client

Initialization

The HTTP/REST support is provided by Ada Util and encapsulated by Swagger Ada. The Ada Util library also takes care of the JSON and XML serialization and deserialization. If you want to use Curl, you should initialize with the following:

with Util.Http.Clients.Curl;
...
   Util.Http.Clients.Curl.Register;

But if you want to use AWS, you will initialize with:

with Util.Http.Clients.Web;
...
   Util.Http.Clients.Web.Register;

After the initialization is done, you will declare a client instance to access the API operations:

with Samples.Petstore.Clients;
...
   C : Samples.Petstore.Clients.Client_Type;

And you should initialize the server base URL you want to connect to. To use the live Swagger Petstore service you can set the server base URL as follows:

  C.Set_Server ("http://petstore.swagger.io/v2");

At this stage, you can use the generated operation by calling operations on the client.

Calling a REST operation

Let's retrieve some pet information by calling the Get_Pet_By_Id operation described previously. This operation needs an integer as input parameter and returns a Pet_Type object that contains all the pet information. You will first declare the pet instance as follows:

with Samples.Petstore.Models;
...
  Pet  : Samples.Petstore.Models.Pet_Type;

And then call the Get_Pet_By_Id operation:

  C.Get_Pet_By_Id (768, Pet);

At this stage, you can access information from the Pet instance:

with Ada.Text_IO;
...
  Ada.Text_IO.Put_Line ("Id      : " & Swagger.Long'Image (Pet.Id));
  Ada.Text_IO.Put_Line ("Name    : " & Swagger.To_String (Pet.Name));
  Ada.Text_IO.Put_Line ("Status  : " & Swagger.To_String (Pet.Status));

The Swagger Ada Petstore illustrates other uses of the generated operations. It allows to list the inventory, list the pets with a given status, add a pet and so on...

Conclusion and references

The OpenAPI Specification provides a standard way to describe REST operations. The Swagger Codegen is the generator to be used to simplify the implementation of REST clients in many programming languages and to generate the documentation of the API. The Ada code generator only supports the client side but the server code generation is under work.

The sources of the petstore samples are available:

The APIs.guru lists more than 550 API descriptions from various providers such as Amazon, Google, Microsoft and many other online services. They are now available to the Ada community!

โŒ
โŒ