mercredi 31 mai 2023

python decorating an object with @

I want to achieve the decorator design pattern in python using the @ syntax, my code:

class Sandwich():
    height = 5
    width = 8

    def ingredients(self):
        print("I have bread")
    
class Cheese_decorator():
    def __init__(self,obj):
        self.obj = obj
        #something else here so the object becomes the same as the passed one except for the methods to decorate below

    #decorated method
    def ingredients(self):
        self.obj.ingredients()
        print("I also have cheese")
     
    #any other method to decorate here

sandwich = Sandwich() # this sandwich wont be decorated
cheese_sandwich = Cheese_decorator(Sandwich()) # this sandwich is decorated

sandwich.ingredients() # prints I have bread
cheese_sandwich.ingredients() # prints I have bread I also have cheese

is there anything I can do like:

sandwich = Sandwich()
cheese_sandwich = @Cheese_decorator
                  sandwich

? I want to have the decorated object as a var

Efficiently handling configuration versions in C# application using design patterns

I am currently developing a tool that aims to support backward compatibility with configuration files. The configuration files are in XML format, which the application parses and maps to the appropriate object type based on the version tag found in the XML.

In the application's business (services) classes, it determines which type to use based on the configuration version. Each configuration version is organized as follows:

    Namespace: Common (includes base classes, shared types, and fields)
    Namespace: V10 (for Config version 1.0) which consumes BaseConfig.cs from the Common namespace
    Namespace: V15 (for Config version 1.5) which also consumes BaseConfig.cs from the Common namespace
    ... and so on

The application determines the appropriate type to use by referencing the configuration version specified in the XML file. Based on this version, the application knows which namespace to access and which specific type to use.

namespace Common.Utils
{
    public static  class ConfigMapper
    {
        public static IConfiguration? ConvertToIConfiguration(BaseConfiguration baseConfig)
        {
            var version = baseConfig.SchemaVersion;

            if (version == SchemaVersion.V10)
            {
                var config = baseConfig as ConfigSchemaV2.V10.Configuration;
                return config;
            }

            if (version == SchemaVersion.V11)
            {
                // ...
            }

            return null;
        }

        public static IConfiguration? ConvertToIConfiguration(string xmlConfig)
        {
            var version = ConfigParserFactory.GetSchemaVersion(xmlConfig);

            if (version == SchemaVersion.V10)
            {
                IConfigParser<ConfigSchemaV2.V10.Configuration> parser = ConfigParserFactory.GetParser<ConfigSchemaV2.V10.Configuration>(xmlConfig);
                var configV1 = parser.Parse(xmlConfig);
                return configV1;
            }

            return null;
        }
    }
}


 private static void Main(string[] args)
        {
            var configPath = @"C:\Users\User\Desktop\config-test.xml";


            //TestCreateConfig(SchemaVersion.V10);

            IConfiguration? conf = TestReadConfig(configPath);

            if (conf is ConfigSchemaV2.V10.Configuration)
            {
                Configuration? config = conf as ConfigSchemaV2.V10.Configuration;
            }
            //else if (conf is ConfigSchemaV2.V11.Configuration)
            //{
            //    Configuration? config = conf as ConfigSchemaV2.V11.Configuration;

            //}
            //else if (conf is ConfigSchemaV2.V12.Configuration)
            //{
            //    Configuration? config = conf as ConfigSchemaV2.V12.Configuration;

            //}
            //else if (conf is ConfigSchemaV2.V13.Configuration)
            //{
            //    Configuration? config = conf as ConfigSchemaV2.V13.Configuration;

            //}
            //else if (conf is ConfigSchemaV2.V14.Configuration)
            //{
            //    Configuration? config = conf as ConfigSchemaV2.V14.Configuration;
            //}

            Console.Read();
        }


As you can see, it's a mess, and there are many classes that need to use the config object directly without making a lot of if-statements.

What could be a good and efficient way to solve this problem?

Thanks.

mardi 30 mai 2023

What are the best practices for organizing terraform configs for setup and applications? [closed]

I am seeking some advice / best practices regarding the organisation of our terraform configurations.
Currently we split the configuration in each environment in two parts.
Part number on is the basic setup, where we create buckets, ECR repos and networking configuration.
In part number two, we deploy several other applications on top of this basic setup. The benefit here is that we can destroy these applications anytime, while destroying the basic setup is not possible anymore, once you have put data into the buckets and ECR repos.

Here are my questions:
First, what is your opinion regarding this strategy?
Second, if you agree that this can make sense, is there a way to share the output variables of the basic setup with the terraform configuration for the other applications? I think I can do that with a data object, and a script fetching the terraform outputs of the basic config, I just want to know if this is a good idea or not.

Thanks for your help!

I am seeking advice regarding the terraform physical design, this is not about an error or problem.

Implementing Facade pattern using Java Interfaces

Currently, I have classes in my module represented by the class diagram below. RestaurantService is a façade interface that is composed of other services like ReservationService and KitchenService. Scope for ReservationService class and KitchenService class is default to hide their visibility from client. From encapsulation perspective this works fine, clients are only aware of RestaurantService and have no knowledge of the internal services. enter image description here

Package Structure

enter image description here

public class RestaurantServiceImpl implements RestaurantService {

   private KitchenService kitchenService;
   private ReservationService reservationService;

   @Override
   public void bookTable(){
      this.reservationService.bookTable();
   }

   @Override
   public OrderDto placeOrder() {
      boolean orderAccepted = this.kitchenService.acceptOrder();
      
      .........
   }

   .........
}

class KitchenService {

   public boolean acceptOrder(){
      .........
   }
}

class ReservationService {

   public void bookTable(){
      .........
   }
}

Now, I want to replace internal service classes with interfaces something like below. enter image description here

With this new design the internal services become public since I can't use protected with Java Interfaces. Therefore, by design there is nothing stopping the client from directly accessing the internal services. Which would lead to two obvious problems:

  1. How will the client know whether it should call bookTable() from RestaurantService or ReservationService.
  2. Leading to fragile code when individual developers decide to call internal service directly rather than using the façade.

So, my question is how to use Java Interfaces for internal services without losing on encapsulation.

I also think this is not a subjective question but more of a design problem for which I am sure there must a design pattern. Therefore, want to learn how you guys handle this in your projects.

Thanks. Looking forward to your inputs.

Print pattern using python [closed]


Print this Pattern. here n indicates number of rows

N = 6

21
20 11
19 12 10
18 13 9 4
17 14 8 5 3
16 15 7 6 2 1

I am not able to find the logic and code What method should be used? Also the difference between elements in not constant

lundi 29 mai 2023

Software architecture for open sources (suricata, open5gs)

Now, I am working with some open-source software in C language: Suricata, Open5g. I know these software are used for different purposes, but I realized that they have same architecture: features are written as modules, then modules are registered with the software. Example, in Suricata, when I want to implement a new protocol, I will need to write some function to parse the packet, then register that function with the main program. Then, when Suricata wants to use this function, there will be a function that manages the spawning of previously registered modules (like this document). Everything is similar with Open5gs or some other C open-source software. It's like a design pattern in C.

I want to learn about this architecture to better understand how it works in open-source C language but don't know its exact name to start with

My question: Is there a term for that software architecture (or implementation)?

dimanche 28 mai 2023

Design classes - common attributes

How can I correctly design such a case?

class A{
string a;
string b;
string c;
string d;
}

class B{
string a;
string b;
string c;
}

class C{
string a;
string d;
}

I tried to create a base class with the shared fields, but then I have to define the shared fields twice

samedi 27 mai 2023

API getting multiple rows as array from database

I have 4 tables:

CREATE TABLE Store (
  id INTEGER PRIMARY KEY,
  name varchar(255) NOT NULL
);

CREATE TABLE Book (
  id uuid PRIMARY KEY,
  name varchar(255) NOT NULL
);

CREATE TABLE BookAvailableInStore (
  book_id uuid NOT NULL REFERENCES Book (id) ON DELETE CASCADE ON UPDATE CASCADE,
  store_id INTEGER NOT NULL REFERENCES Store (id) ON DELETE CASCADE ON UPDATE CASCADE,
  PRIMARY KEY (book_id, store_id)
);

CREATE TABLE UserBookInterest (
  user_account_id uuid NOT NULL REFERENCES UserAccount (id) ON DELETE CASCADE ON UPDATE CASCADE,
  book_id uuid NOT NULL REFERENCES Book (id) ON DELETE CASCADE ON UPDATE CASCADE,
  PRIMARY KEY (user_account_id, book_id)
);

Ultimately, I would like my API to return all books that are of interest to a given user, with the stores they can find them:

[
  {"book_id":1, "book_name":"My Book 1", "stores":[{"id":1, "name": "Store 1"}, {"id":2, "name": "Store 2"}]},
  {"book_id":2, "book_name":"My Book 2", "stores":[{"id":1, "name": "Store 1"}]},
  {"book_id":3, "book_name":"My Book 3", "stores":[]},
]

I am not sure what is the recommended clean approach to get such a result:

  1. Should I write a single SQL query that returns all the books/store availability
book_id, book_name, store_id, store_name
1, "book 1", 1, "store 1"
1, "book 1", 2, "store 2"
2, "book 2", 1, "store 1"
3, "book 3", null, null

and then loop through all rows and "merge" the stores for each book?

  1. Or should I get the list of books of interest for the user, and then for each book have a new query populating the "stores" information? (it would mean that if the user has 300 books of interest, it would run 301 queries to the DB)?
  2. Or another better way?

If it is relevant, I am using NodeJS and Postgres.

vendredi 26 mai 2023

How do I make the "builder" design pattern and Spring dependency injection compatible with each other?

How compatible are the "builder" design pattern and Spring dependency injection? Consider this code

    @Test
    @Sql(executionPhase = BEFORE_TEST_METHOD, value = BASE_SCRIPT_PATH + "GetCommentTest/before.sql") // inserting sample rows
    @Sql(executionPhase = AFTER_TEST_METHOD, value = BASE_SCRIPT_PATH + "GetCommentTest/after.sql") // truncating
    private void getPageOneDefaultTest() throws Exception {
        MockHttpServletResponse response = mockMvc.perform(get(BASE_URI + "page/" + 1)
                        .header(HttpHeaders.AUTHORIZATION, token))
                .andExpect(status().isOk())
                .andReturn()
                .getResponse();

        /*
        The whole idea with "expectation testers" may look a bit unusual, but if you consider that
        I also have methods getPageOneSizeFiveTest(), getPageTwoSizeFiveTest() (probably, I
        should add more of them for a better coverage), you should realize it removes a lot of
        code duplication
        */

        expectationTester = new GetCommentPageExpectationTester.Builder(response)
                .setExpectedPageCount(10)
                .setExpectedPageDtoListSize(10)
                .setExpectedOwnerUsername("mickey_m")
                .build();

        expectationTester.test();
    }
public class GetCommentPageExpectationTester implements ExpectationTester {
    private final String serializedResponseBody;
    private final int expectedPageCount;
    private final int expectedPageDtoListSize;
    private final int expectedFirstCommentId;
    private final String expectedCommentText;
    private final int expectedQuestionId;
    private final int expectedOwnerId;
    private final String expectedOwnerUsername;
    private final ObjectMapper objectMapper;

    private GetCommentPageExpectationTester(Builder builder) {
        this.serializedResponseBody = builder.serializedResponseBody;
        this.expectedPageCount = builder.expectedPageCount;
        this.expectedPageDtoListSize = builder.expectedPageDtoListSize;
        this.expectedFirstCommentId = builder.expectedFirstCommentId;
        this.expectedCommentText = builder.expectedCommentText;
        this.expectedQuestionId = builder.expectedQuestionId;
        this.expectedOwnerId = builder.expectedOwnerId;
        this.expectedOwnerUsername = builder.expectedOwnerUsername;
        this.objectMapper = new ObjectMapper();
    }
    @Override
    public void test() throws JsonProcessingException {
        Data<Page<QuestionCommentResponseDto>> deserializedResponseBody =
                objectMapper.readValue(serializedResponseBody, Data.class); // once I post it on CodeReview, you may comment on this unchecked cast
        assertNotNull(deserializedResponseBody.getData());
        Page<QuestionCommentResponseDto> page = deserializedResponseBody.getData();
        assertEquals(expectedPageCount, page.getCount());
        assertNotNull(page.getDtos());
        List<QuestionCommentResponseDto> dtoList = page.getDtos();
        assertEquals(expectedPageDtoListSize, dtoList.size());

        QuestionCommentResponseDto dto;
        for (int i = 1; i <= dtoList.size(); i++) {
            dto = dtoList.get(i);
            assertEquals(expectedFirstCommentId, dto.getId());
            assertEquals(expectedQuestionId, dto.getQuestionId());
            assertEquals(expectedCommentText, dto.getText());
            assertNotNull(dto.getCreatedDate());
            assertNotNull(dto.getModifiedDate());

            AccountResponseDto actualOwner = dto.getOwner();
            assertEquals(expectedOwnerId, actualOwner.getId());
            assertEquals(expectedOwnerUsername, actualOwner.getUsername());
        }
    }
    public static class Builder {
        private final String serializedResponseBody;
        private int expectedPageCount;
        private int expectedPageDtoListSize;
        private int expectedFirstCommentId = 1;
        private String expectedCommentText = "text";
        private int expectedQuestionId = 1;
        private int expectedOwnerId = 1;
        private String expectedOwnerUsername;

        public Builder(MockHttpServletResponse response) throws UnsupportedEncodingException {
            this.serializedResponseBody = response.getContentAsString();
        }

        public Builder setExpectedPageCount(int expectedPageCount) {
            this.expectedPageCount = expectedPageCount;
            return this;
        }
        public Builder setExpectedPageDtoListSize(int expectedPageDtoListSize) {
            this.expectedPageDtoListSize = expectedPageDtoListSize;
            return this;
        }
        // the rest of the setters are omitted
        public GetCommentPageExpectationTester build() {
            return new GetCommentPageExpectationTester(this);
        }
    }
}

When I call build(), it invokes a private constructor and returns the instance of the top-level class copying the field values of the Builder. Now, suppose I want ObjectMapper autowired. I annotate both the top-level class and the Builder as @Components. Then if I call build(), ObjectMapper isn't going to be injected, is it?, since the top-level class instance is going to be created with a simple constructor call, it's not coming from the Spring container, is it? Can I have a builder like that while also autowiring dependencies? While in this case I can simply initialize the ObjectMapper field with a no-args constructor (hoping it's going to be the same ObjectMapper as the autowired one), it may make sense for "expectation testers" that use an EntityManager

// most fields are omitted for brevity
@Component
public class GetCommentExpectationTester implements ExpectationTester {
    @PersistenceContext
    private EntityManager entityManager;
    @Override
    public void test() {
        assertTrue(entityManager.createQuery("""
                SELECT COUNT(qc.id) = 1
                FROM QuestionComment qc
                JOIN qc.owner ow
                JOIN qc.question q
                WHERE qc.createdDate IS NOT NULL
                AND qc.modifiedDate IS NOT NULL
                AND qc.text = 'text'
                AND ow.id = 1
                AND q.id = 1
                """, Boolean.class)
                .getSingleResult());
    }

I can autowire a field, an ObjectMapper or an EntityManager for example, at the Builder level. But then I won't be able to create a Builder instance and pass a response right in a test method like that, will I?

I can also simply pass the autowired EntityManager as a method argument (the test class has one) when creating a Builder instance. But since reading Robert Martin's books, I am super-wary of passing anything. The less you pass, the better, that's my takeaway

What design pattern should be implemented to make my code accord with Open-Closed Principle

Here is the code that violates the open-closed principle:

public Node? Run(Node node)
{
    if (node.NodeType == Enum.NodeTypeEnum.ManualTask)
    {
        // do something
        return node.NextNodes.FirstOrDefault();

    }
    else if (node.NodeType == Enum.NodeTypeEnum.ScriptTask)
    {
        // do something
        return node.NextNodes.FirstOrDefault();
    }
    else if (node.NodeType == Enum.NodeTypeEnum.ExclusiveGateway)
    {
        // do something
        return node.NextNodes.FirstOrDefault();
    }
}

Node entity:

public class Node: EntityBase
{
    public NodeTypeEnum NodeType { get; set; }
    public List<Node>? NextNodes { get; set; }
    public string? NodeCondition { get; set; }
    public int ScriptId { get; set; }
}

In the code, we have a node entity which has many types. For each types, we should do some specific operation.

I try to refactor the method as follows:

NodeRunner.cs file:

public class NodeRunner: INodeRunner
{
    public virtual bool IsMatch(NodeEntity node)
    {
        throw new NotImplementedException();
    }

    public virtual Node Run(NodeEntity node)
    {
        throw new NotImplementedException();
    }
}

ManualTask class:

public class ManualTask : NodeRunner
{
    public override bool IsMatch(NodeEntity node)
    {
        return node.NodeType == NodeType.Manual;
    }

    public override Node Run(NodeEntity node)
    {
        return node.NextNodes.FirstOrDefault();
    }
}

ScriptTask class:

public class ScriptTask : NodeRunner
{
    // ...
    public override bool IsMatch(NodeEntity node)
    {
        return node.NodeType == NodeType.Script;
    }

    public override Node Run(NodeEntity node)
    {
        _scriptService.Execute(node.ScriptId);
        return node.NextNodes.FirstOrDefault();
    }
}

ExclusiveGateway.cs:

public class ExclusiveGateway: NodeRunner
{
    public override bool IsMatch(NodeEntity node)
    {
       return node.NodeType == NodeType.ExclusiveGateway;
    }

    public override Node Run(Node node)
    {
        if (node.NextNodes != null)
        {
            foreach (var nextNode in node.NextNodes)
            {
                if (_evaluateGatwayCondition.Evaluate(nextNode.NodeCondition, ""))
                {
                    return nextNode;
                }
            }
        }

        return new Node();
    }
}

And the ProcessService.cs:

public class ProcessService : IProcessService
{
    private readonly List<NodeRunner> NodeBrances;

    public ProcessService()
    {
        NodeBrances = new List<NodeRunner>
        {
            new ManualTask(),
            new ScriptTask(),
            new ExclusiveGateway()
        };
    }

    public Node Run(Node node)
    {
        return NodeBrances.First(nb => nb.IsMatch(node)).Run(node);
    }
}

ExclusiveGateway does not work and throws a NotImplementedException().

What should I do?

Java implementation of splitting a Very Large Database into live and archive [closed]

I'm wondering what is the best design and most efficient, best way to implement the following in java:

I have an application in java that when a user makes a request, the app queries the database.

This large database has various tables and these tables have millions of records. I want to split the database into a live database and an archive database.

Live database contains all records that have a date which is 7 days from today's date (the date column depends on the table), records older than 7 days are archived in the ArchiveDatabase.

So whenever a request comes in from a user into our java application, we need to route the request based on the date on the request to either the LiveDatabase or the ArchiveDatabase, therefore greater than 7 days is ArchiveDatabase and less than 7 days is LiveDatabase.

My Personal approach:

A service class that receives the date and other params and forwards to a main DAO class. DAO Class has a dateChecker service which does the logic of <7 days then returns LiveDatabaseDao if >7 days then returns ArchiveDatabaseDao.

then the main DAO class uses that relevant dao to run queries using the returned DAO.

Maybe there is a better approach?

jeudi 25 mai 2023

Is my modified python monad still a monad?

I recently learned how monads work and how they can be used to take more control over side effects. I wrote a few to calculate the time of composed functions, and to ofc take care of logging. One annoying thing I noticed is that I had to repeatedly write .bind(func) instead of simply .func, which is a slight annoyance.

So I then tried to include that in my logger monad and this is what I ended up with:

class IterBetter:
    def __init__(self, value: Iterable[T], log: List[str] = None):
        self.value = value
        self.log = log or []
        self.original_type = type(value)
        
    # convenience methods
    def __repr__(self):
        return f"{self.value}"
    
    def __getitem__(self, index):
        return self.value[index]
    
    def __setitem__(self, index, value):
        self.value[index] = value
    
    
    @staticmethod
    def bindify(f):
        
        def wrapper(self, func):
            result, msg = f(self, func)
            return IterBetter(result, self.log + [msg])
        
        return wrapper
    
    @bindify
    def newmap(self, func):
        msg = f"Mapping {func} over {self.value}"
        mapped = self.original_type(map(func, self.value))
        return mapped, msg
    
    @bindify
    def newfilter(self, func):
        msg = f"Filtering {func} over {self.value}"
        filtered = self.original_type(filter(func, self.value))
        return filtered, msg

Now you can write something like

mylst = IterBetter([1, 2, 3, 4, 5])
newlst = (
    mylst
    .newmap(lambda x: x + 1)
    .newfilter(lambda x: x % 2 == 0)
    .newmap(lambda x: x * 3)
)

Which is very nice imo, it's definitely more convenient than python's built-in maps and filers (but comprehensions exist, so this isn't all that practical).

However... Why would we want to use a design like that for the class? Like what's the advantage of returning a log message instead of just appending it to the log list? Either way we have to change the original log.

And is this modified implementation still a monad?

Designing classes to help Junit Testing

I will try to explain through pseudocode a code quality or design issue that I encountered while testing a spring boot application:

controllerMethod(@RequestParam(version) String version){

 service.generateFile(version)


}

class Service {

private map= new HashMap<>();

void generateFile(version){
String rVersion = fetchRversion(version);
String json=makeApiCall(url+rVersion);
build(map);
generateData(json)

}
generateData(json){
// uses map
}

The above way of coding cause trouble when testing the generateData method. So if I have the JSON, I pass it to the generateData function. The trouble will be that map is built inside the generateFile function.
So it won't work. Either I built the map inside the test function for generateData or there could be some way of creating the Service class object with the map so that no testing function has to care about building or instantiating any other data. Since the version is passed at run time and based on that the map is built, will it be appropriate to have a separate build function inside the service class which can be called to setup all the required things?
Any alternative to this approach?

Extract wildcard string (* asterisk only) from a set of strings/texts?

Is there an algorithm or code/lib (NodeJS preferably), to extract wildcard string from a set of strings or texts.

For example, following are the set of strings (forgive my english):

apple pie is not too so good
apple pie is not so good
apple pie is too good

I shall be able to extract a wildcard string with asterisk * only, like this:

apple pie is * good

There are other special characters in wildcard, but I want to use only * asterisk.

Please let me know if more information required.

Is this an antipattern? [closed]

I'm building a streamlit app that connects to some third-party service, therefore you need to provide an API key to use it. My current approach is like this:

if os.environ['api_key']:
  def main_component():
    ...
  main_component()
else:
  def api_key_form():
    #get api key from form and store in os.environ
  api_key_form()


Is this a antipattern or unusual but fine?

mercredi 24 mai 2023

Code reusability issue when creating API with Flask

I have code reusability issue in my code, this is one of example of routes folder file, it's users.py:

from models import User, ApiResponse
from mongoengine import ValidationError
from flask import request
from utils import get_timestamp
from copy import deepcopy
from authentication import check_password_hash, generate_password_hash, tokenizer, detokenizer, get_data_by_token
from validation import is_identity_valid, is_role_valid
from env import ENV


def create_user():
  try:
    # Authentication check
    auth = request.cookies.get('auth')  # type: ignore
    if auth is None:
      return ApiResponse(401, 'fail', 'Unauthorized, auth is none.', None)
    data = get_data_by_token(str(auth))
    if data is None:
      return ApiResponse(401, 'fail', 'Unauthorized, token is none.', None)
    user, newToken = data
    if user is None:
      return ApiResponse(401, 'fail', 'Unauthorized, user is none.', None)
    if not str(user.role) in ['admin']:
      return ApiResponse(403, 'fail', 'Previlege is forbidden.', None)

    # Get timestamp
    # 1683478800000 adalah timestamp proyek ini dimulai
    timestamp = get_timestamp()

    body = request.json
    if body:
      userReq = User(**body['data'])  # JSON deserialize

      if not is_identity_valid(str(userReq.identity)):
        return ApiResponse(400, 'fail', 'Invalid identity.', None)

      if not is_role_valid(str(userReq.role)):
        print(userReq.role)
        return ApiResponse(400, 'fail', 'Invalid role.', None)

      # Mencari user yang ada di database
      userDbList = User.objects(identity=userReq.identity)  # type: ignore
      if len(userDbList) != 0:
        return ApiResponse(409, 'fail', 'User already exists.', None)

      userReq._id = timestamp
      userReq.password = generate_password_hash(str(userReq.password))
      userReq.save()

      resp = ApiResponse(
          201, 'success', 'User created successfully.', userReq.to_mongo())
      if newToken:
        resp.set_cookie('auth', newToken, path=ENV.API_ENDPOINT)
      return resp
    else:
      return ApiResponse(400, 'fail', 'Bad request.', None)
  except ValidationError:
    return ApiResponse(422, 'fail', 'Unprocessable entity.', None)
  except Exception as e:
    print(e)
    return ApiResponse(500, 'fail', 'Internal server error.', None)


def get_users():
  try:
    # Authentication check
    auth = request.cookies.get('auth')  # type: ignore
    if auth is None:
      return ApiResponse(401, 'fail', 'Unauthorized, auth is none.', None)
    data = get_data_by_token(str(auth))
    if data is None:
      return ApiResponse(401, 'fail', 'Unauthorized, token is none.', None)
    user, newToken = data
    if user is None:
      return ApiResponse(401, 'fail', 'Unauthorized, user is none.', None)
    if not str(user.role) in ['admin']:
      return ApiResponse(403, 'fail', 'Previlege is forbidden.', None)

    users = User.objects().all()  # type: ignore
    userList = [user.to_mongo() for user in users]
    resp = ApiResponse(
        200, 'success', 'Users retrieved successfully.', userList)
    resp.set_cookie('auth', newToken, path=ENV.API_ENDPOINT)
    return resp
  except Exception as e:
    print(e)
    return ApiResponse(500, 'fail', 'Internal server error.', None)


def get_user(user_id):
  try:

    # Authentication check
    auth = request.cookies.get('auth')  # type: ignore
    if auth is None:
      return ApiResponse(401, 'fail', 'Unauthorized, auth is none.', None)
    data = get_data_by_token(str(auth))
    if data is None:
      return ApiResponse(401, 'fail', 'Unauthorized, token is none.', None)
    user, newToken = data
    if user is None:
      return ApiResponse(401, 'fail', 'Unauthorized, user is none.', None)

    # Admin check
    if not str(user.role) in ['admin']:
      if int(user._id) != int(user_id):  # type: ignore
        print(int(user._id), int(user_id))  # type: ignore
        return ApiResponse(403, 'fail', 'Forbidden.', None)

    userList = User.objects(_id=int(user_id))  # type: ignore
    if len(userList) == 0:
      return ApiResponse(404, 'fail', 'User not found.', None)
    userReq = userList[0]

    resp = ApiResponse(
        200, 'success', 'User retrieved successfully.', userReq.to_mongo())
    resp.set_cookie('auth', newToken, path=ENV.API_ENDPOINT)

    return resp
  except Exception as e:
    print(e)
    return ApiResponse(500, 'fail', 'Internal server error.', None)


def put_user(user_id):
  try:

    # Authentication check
    auth = request.cookies.get('auth')  # type: ignore
    if auth is None:
      return ApiResponse(401, 'fail', 'Unauthorized, auth is none.', None)
    data = get_data_by_token(str(auth))
    if data is None:
      return ApiResponse(401, 'fail', 'Unauthorized, token is none.', None)
    user, newToken = data
    if user is None:
      return ApiResponse(401, 'fail', 'Unauthorized, user is none.', None)

    # Admin check
    isAdmin = True
    if not str(user.role) in ['admin']:
      if int(user._id) != int(user_id):  # type: ignore
        return ApiResponse(403, 'fail', 'Forbidden.', None)
      isAdmin = False

    userList = User.objects(_id=int(user_id))  # type: ignore
    if len(userList) == 0:
      return ApiResponse(404, 'fail', 'User not found.', None)
    userOld = userList[0]

    body = request.json
    if body:
      oldUser = deepcopy(userOld)
      newUser = User(**body['data'])

      # Field update
      if newUser.password is not None:
        userOld.password = generate_password_hash(str(newUser.password))

      if is_role_valid(str(newUser.role)) and isAdmin:
        userOld.role = str(newUser.role)

      userOld.save()
      response = {
          'old_data': oldUser.to_mongo(),
          'new_data': userOld.to_mongo()
      }
      resp = ApiResponse(200, 'success', 'User updated succesfully.', response)
      resp.set_cookie('auth', newToken, path=ENV.API_ENDPOINT)
      return resp
    else:
      return ApiResponse(400, 'fail', 'Bad request.', None)
  except Exception as e:
    print(e)
    return ApiResponse(500, 'fail', 'Internal server error.', None)


def delete_user(user_id):
  try:
    # Authentication check
    auth = request.cookies.get('auth')  # type: ignore
    if auth is None:
      return ApiResponse(401, 'fail', 'Unauthorized, auth is none.', None)
    data = get_data_by_token(str(auth))
    if data is None:
      return ApiResponse(401, 'fail', 'Unauthorized, token is none.', None)
    user, newToken = data
    if user is None:
      return ApiResponse(401, 'fail', 'Unauthorized, user is none.', None)

    # Admin check
    if not str(user.role) in ['admin']:
      return ApiResponse(403, 'fail', 'Forbidden.', None)

    # Fetch the user from the collection based on the provided ID
    userList = User.objects(_id=int(user_id))  # type: ignore

    # Check if user found
    if len(userList) == 0:
      return ApiResponse(404, 'fail', 'User not found.', None)
    userReq = userList[0]

    # Remove from database
    userReq.delete()

    resp = ApiResponse(200, 'success', 'User deleted successfully.', None)
    resp.set_cookie('auth', newToken, path=ENV.API_ENDPOINT)
    return resp
  except Exception as e:
    print(e)
    return ApiResponse(500, 'fail', 'Internal server error.', None)


def login_user():
  try:
    body = request.json
    if body:
      userReq = User(**body['data'])
      userList = User.objects(identity=str(userReq.identity))  # type: ignore
      if len(userList) == 0:
        return ApiResponse(401, 'fail', 'Wrong authentication.', None)
      user = userList[0]

      if not check_password_hash(str(user.password), str(userReq.password)):
        return ApiResponse(401, 'fail', 'Wrong authentication.', None)

      # Authorization return token
      dataForToken = {
          'identity': user.identity
      }
      token = tokenizer(dataForToken)
      if token is None:
        raise Exception('Token generating error.')
      user.save()

      resp = ApiResponse(
          200, 'success', f'User {user.identity} logged in successfully.', token)
      resp.set_cookie('auth', token, path=ENV.API_ENDPOINT)
      return resp
    else:
      return ApiResponse(400, 'fail', 'Bad request.', None)
  except Exception as e:
    print(e)
    return ApiResponse(500, 'fail', 'Internal server error.', None)


def logout_user():
  try:
    # Authentication check
    auth = request.cookies.get('auth')  # type: ignore
    if auth is None:
      return ApiResponse(401, 'fail', 'Unauthorized, auth is none.', None)
    data = get_data_by_token(str(auth))
    if data is None:
      return ApiResponse(401, 'fail', 'Unauthorized, token is none.', None)
    user, newToken = data
    if user is None:
      return ApiResponse(401, 'fail', 'Unauthorized, user is none.', None)
    if not str(user.role) in ['admin']:
      return ApiResponse(403, 'fail', 'Previlege is forbidden.', None)

    # Deauthentication
    resp = ApiResponse(
        200, 'success', f'User {user.identity} logged out successfully.', None)
    resp.set_cookie('auth', '', path=ENV.API_ENDPOINT)
    return resp
  except Exception as e:
    print(e)
    return ApiResponse(500, 'fail', 'Internal server error.', None)

I'm struggle finding way how to keep it simple of every route. Mainly cookie store.

Let me know if you want to know objects or class from my code example.

I think I have really bad design pattern. Here is my project structure test

What is the benefit of using a fanout micro-service in nodeJS?

I was just reading this article HERE. Basically the user suggesting that a sample twitter architecture be split up into multiple micro-services , see the diagram below :-

Sample twitter architecture.

However, there is this one service though which i see multiple calls being passed though , not directly through user action but it sits in between. the Fanout Service, what exactly is a fanout service ? what purpose does it serve. So far what i understand is it sends data to multiple other services, But whats the advantage ? When exactly do we leverage a Fanout micro-service ? What value does it add ?

What is the best way to avoid chained if-else condition to invoke different class function?

I am writing a GraphQL Query API which takes filter as input. Based on the filter I need to invoke different object function.

API function signature

public GrantsConnection fetch(GrantFilter filter)

GrantFilter has following attributes.

public class GrantFilter {
  private Boolean isPrimary;
  private String profileId;
  private String entityId;
}

The filter can be a combination of one or two or all attributes.

My approach

public GrantConnection(GrantFilter filter) {
  if(filter.getIsPrimary() != null
     && filter.getProfileId() == null
     && filter.getEntityId() == null) {
    // invoke a function
  } else if(filter.getIsPrimary() == null
     && filter.getProfileId() != null
     && filter.getEntityId() == null) {
     // invoke different function
  } else if(filter.getIsPrimary() == null
     && filter.getProfileId() == null
     && filter.getEntityId() != null
     // invoke 3rd function
  }
 // other combinations
}

All the function invoked from conditionals are objects which implement same interface. What is the best way to write this in spring?

mardi 23 mai 2023

Are classic and dynamic decorators limited to only the way they are applied or extend to functionality differences as well?

I am pretty new here and have been reading about Python Decorators and came across 2 types of decorator patterns.

  1. Classic Decorators
  2. Dynamic Decorators

What I understood as the difference between the two is, Classic decorators do not allow access to underlying object attributes. Now while the text part is understood, I wrote a code to see it for myself and I am unable to determine the category of decorator used in the example.

As for me, from my experiments and trials, I can change the attributes and see them reflected as well.

Code that I wrote to demonstrate this, is as below.

from dataclasses import dataclass, field
import random
import string
import time

def timeit(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        ret = func(*args, **kwargs)
        stop = time.time()
        print(f'>>> Total time taken : {int((stop-start)*1000)}ms')
        return ret
    return wrapper

def generate_id(classname):
        return classname.upper() + "".join(random.choices(string.ascii_uppercase, k=12))

@dataclass
class Person:
    name: str
    email: str
    address: str
    age: int
    id: str = field(init=False) #, default_factory=generate_id)
    _search_string: str = field(init=False, repr=False)

    def __post_init__(self) -> None:
        print(f'{type(self).__name__}')
        self.id = generate_id(classname=f'{type(self).__name__}')
        self._search_string = f'{self.name} {self.address}'
        time.sleep(1)

    def __str__(self) -> str:
        print(f'{type(self).__name__}')
        return f'{self.name} lives in {self.address}'

@timeit
def main() -> None:
    person = Person(name="Amitabh", email="amitabh@ainebula.in", address="India", age=31)
    print(person)
    print(repr(person))
    person.address = "Bangalore, India"
    print("After change")
    print(person)
    print(repr(person))

if __name__ == '__main__':
    main()

When I execute the program, the output of this program is as below. As you can see that when I changed the attribute, the change reflect well. What is the key point I am missing here? Any pointers?

Person
Person
Amitabh lives in India
Person(name='Amitabh', email='amitabh@ainebula.in', address='India', age=31, id='PERSONDUQLSUAGCJJJ')
After change
Person
Amitabh lives in Bangalore, India
Person(name='Amitabh', email='amitabh@ainebula.in', address='Bangalore, India', age=31, id='PERSONDUQLSUAGCJJJ')
>>> Total time taken : 1004ms

If anyone of you need more details on the question, kindly comment and I shall provide more info. As on now, this is the best I could frame my question.

If this does not follow the Classic Decorator pattern, I want to know how and why.

old fashioned repository pattern with DDD [closed]

Is it a good idea to use old fashioned repository pattern in an API implementing DDD?

Rather than using the repository pattern in th DDD way (in which case, a get method should directly return an hydrated domain model), we use repository a more classical way: a get method would return an ITO (stands for: Infra Transfer Object, which is a presenter of the retrieved data). The domain model is then hydated using one (or more) query.ies from repository.ies. The aim is to have more reusability of our repository methods, but is it really useful? Any thoughts or return of experience about this approch?

lundi 22 mai 2023

Spring microservices architecture request

i'm requiered to build a spring microservices system where an admin manage supervisors and interns, supervisors create and assign tasks to interns, and interns update task statuses and upload reports for completed tasks.

Can you help me for the architecture of microservices ?

and if it's possible to have a database per service, because it's part of the requierement.

thank you for your help!

i did build a monolith application if that can make it easy for me

Choosing the best Design Pattern

I am planning to create a link-shortening service. I am using MERN and Redis for caching db. I am still thinking about a design pattern that I should use for it. I am trying some approaches.

  1. Create a full monolithic app, including all the front-end, user management, link management, and link-clicking mechanism
  2. Create a microservice for the link clicking and another for other all tasks.

What would be most cost-effective, I am hoping to get ~100,000 clicks per month. When choosing a hosting service, what should I choose?

I want to deploy this on AWS. If we choose 1st approach what would be the most suitable service, with a minimum budget? and if not for other approch

Vertical Slice Architecture Feature Dependency

I am using clean architecture and DDD less than one year and currently looking to vertical slice architecture to organize my code more better but I have an important question here:

If I have features like this

  • getCart
  • getProfileInfo
  • getShippingAddress
  • getPaymentMethod

And now I need to implement a new feature called placeOrder and this feature depends on some other features like getCart, getProfileInfo, getShippingAddresss, getPaymentMethod, what should I do in that case, can I inject other features in placeOrder service, or should I duplicate the code in this feature to be self-contained?

How can I create a random pattern flashing at specific frequency in Python for GIF creation?

I am trying to write a code that creates a random pattern flashing (twinkling) at a specific frequency. Below is the code I am using, but the problem is that, different frequencies (frame rates) that I set for the pattern to flash will show the same frame rate within ImageJ (9 fps). Is it a code problem or display limitation? Would appreciate any help!

import numpy as np
import imageio

def create_twinkling_gif(frequency, duration, sparsity, output_path):
    frame_duration = 1 / frequency
    total_frames = int(duration * frequency)
    num_sparsity_pixels = int(sparsity * 256 * 256)

    # Create a white background
    background = np.ones((256, 256), dtype=np.uint8) * 255

    # Generate a fixed random pattern
    pixel_values = np.random.random((256, 256))
    sparsity_indices = np.random.choice(256 * 256, num_sparsity_pixels, replace=False)
    pixel_values.ravel()[sparsity_indices] = 1

    # Create the on and off frames based on the fixed pattern on white background
    on_frame = np.where(pixel_values == 1, 0, background).astype(np.uint8)
    off_frame = background

    frames = []
    for frame_num in range(total_frames):
        if frame_num % 2 == 0:
            frames.append(on_frame)
        else:
            frames.append(off_frame)

    # Save the frames as a GIF using imageio
    imageio.mimsave(output_path, frames, duration=frame_duration)

# Set the parameters for the twinkling GIFs
frequency = 60  # Hz
duration = 5  # seconds
step_size = 0.05

# Generate GIFs for different sparsity values
for i in range(21):
    sparsity = i * step_size
    output_path = f"twinkling_{sparsity:.2f}.gif"
    create_twinkling_gif(frequency, duration, sparsity, output_path)

Output:

Output gif with 50% sparsity

dimanche 21 mai 2023

Is having a Static Map like this a bad practice?

I want to have some important classes available through out the app, like so:

private static final HashMap<Class<?>, Object> _globals = new HashMap<>();

public MainClass(){
     _stateManager = new StateManager();
     _inputManager = new InputManager();
     _toolManager = new ToolManager();
     _viewManager = new ViewManager();
     _globals.put(StateManager.class, _stateManager);
     _globals.put(InputManager.class, _inputManager);
     _globals.put(ToolManager.class, _toolManager);
     _globals.put(ViewManager.class, _viewManager);
}

From what I've been researching, static vars are always discouraged, but I feel like this might be ok, because I'm not actually keeping any static state. The main purpose of _globals if to have it available for example in the class TextFieldController without having to pass it to the constructors, from the main class all the way to there, going through classes that might not need it.

Is this ok or is there any problems i'm not seeing ?

Design and Architecture in python path of studying

cuting to the chase I am a self tought programmer, and I hit a brick wall. I am felling very well in python but my design/architecture skills aren't well developed and I don't know how to manage large programs, how to make them easy to maintain and scale, how to plan well OOP. I was looking for some online resources and I found one which fits my excpectations truly:

x) Software Design and Architecture Specialization on coursera - https://www.coursera.org/specializations/software-design-architecture

but the course is provided in Java, and I don't have any prior experience in java. That's why I would like to ask you some more experience programers for an advice.

Do you have any specyfic resources which could give me deep and collage level understanding and knowledge about software design/archtecture (this is how I prefer to study any topic - very deep to get all of its logic and genesis).

Or maybe a good idea is to make 2/3h course in java with mosh for example or at any udemy site and follow with coursera course.

What is important to me to not only read about theory but also has a possibility to check my knowledge in a form of assigments. All courses I found on internet aren't made in python.

I would be very grateful for any advice, and thanks for you help ! :)

samedi 20 mai 2023

Flutter: How do I achieve this button layout for my UI design in flutter?

https://dribbble.com/shots/4602735-Sketch-Symbol-Example-With-Gradients-Alternative-Radius

Flutter: How do I achieve this button layout for my UI design?

i am learning flutter. i want to create button design like this in my flutter.

how to create design like this. this is the sketch: https://drive.google.com/file/d/1KjIoiYSK3affPyIZa4V_pQwqTFih3yes/view?usp=sharing how to button design like this

Java - design pattern State [closed]

I am doing a java program,in this I have a class "Booking" where I have a state with 3 possibilities: "Check-in not done", "Ongoing", "Check-out done". The default state is the first one ("Check-in not done"), then the user change the state until the last one ("Check-out done").

I want that a message is printed on screen only once when the state is reached. I had thought of using the desing pattern "State" to implement this. Is it a correct choice? If it is how can write this part of code?

vendredi 19 mai 2023

Redirect only few Kafka messages to new application to check flow is good

I am aware of consumer group concept in kafka.We have Application A which currently takes a lot of traffic. We built a new Application B which also listens to same kafka topic. We initially want new Application B to take a very small percentage of traffic like if Application A process 1000 messages then I want Application B to get 1 message and process it. That way I can check if new Application processing is good before redirecting all traffic to new Application B. Both applications will have diff consumer group and different db. How do we design so that new Application B gets only a small percentage of population and avoid duplicate processing between application A and Application B

How to have a mechanism in Kafka to redirect only small percentage to new appliation

Is there a simple pattern in Typescript to write a wrapper Class vor some type without explicily copying every attribute? [duplicate]

I often receive raw JSON data from the outer world. (e.g. via http requests) Often this data represents entities I want to do operations on. For this purpose I want to write a wrapper class for some given entity, but without explicitly copying each attribute to the class! Is there a way to do this in a type save manner?

Here is my usecase

// This is a wrapper class
new class User {
 // some unknown implementation
}

interface UserDto {
    readonly id: string;
    readonly friends: string[];
}

const user = new User(userDto);
console.log(user.id);
console.log(user.friendsConut()); // this an extension to UserDto

And here is the implementation for the User class I want to avoid, for the sake of dry code:

class User {
    readonly id: string;
    readonly friends: string[];
    constructor(dto: UserDto){
         this.id = dto.id;
         this.friends: dto.friends;
    }

    frindsCount(){
        return this.friends.length
    }

Singleton class not shared between different modules in Python

I'm trying to implement a singleton pattern in Python to share a class between different modules. I'm experiencing some issues where the same instance is not being shared between different appearances of the singleton class.

Here is my code:

from some.module import SomeClass

class SingletonMeta(type):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            instance = super().__call__(*args, **kwargs)
            cls._instances[cls] = instance
        return cls._instances[cls]

class SomeClassFactory(metaclass=SingletonMeta):

    _data1 = None
    _data2 = None
    _some_class_instance = None

    @classmethod
    def get_some_class_instance(cls):
        return cls._some_class_instance

    @classmethod
    def initialize_instance(cls, data1, data2):
        if not cls._some_class_instance:
            cls._some_class_instance = SomeClass(data1, data2)
            cls._data1 = data1
           

Module 2 (some.services):

from typing import Optional, List
from some.factories import SomeClassFactory

class SomeClassService:

    def get_some_class_instance(self):
        factory = SomeClassFactory()
        return factory.get_some_class_instance()

Testing on Python Console:

from some.factories import SomeClassFactory
factory = SomeClassFactory()
factory.initialize_instance(data1, data2)
some_instance = factory.get_some_class_instance()

from some.services import SomeClassService
service_class = SomeClassService()
some_instance_2 = service_class.get_some_class_instance()  # Returns None

The expected behaviour is that some_instance and some_instance_2 would refer to the same instance of SomeClass. However, some_instance_2 is None.

Am I misunderstanding how the singleton pattern should work in Python, or is there something wrong with my implementation? Any help is greatly appreciated.

mercredi 17 mai 2023

How to best query from a csv repeatedly throughout the day in a simulation code

I'm trying to write a simulation code in python. This simulation code relies on inputs for a large csv file, and there is a separate csv file for each day in the simulation. I need to make numerous queries (the queries are based on time, which are columns in the csv file) each simulation day.

I'm thinking of using pandas.read_csv to read this in as a dataframe, and store the result and then query from this dataframe. One coding requirement is I don't want the dataframe stored at the query site.

I think the easiest way to do this is with a class, e.g.,

import pandas as pd
class DailyCSVLoader:
  def __init__(filepath):
    self.df = pd.read_csv(filepath)
  def query(time):
    # return the rows corresponding to time

with usage:

import datetime

path = "/path/to/csv/file/filename.csv"
time = datetime.datetime(year=2020, month=1, day=1, hour=12, minute=2, second=0)
loader = DailyCSVLoader(path)
loader.query()

However, for my particular codebase, it might be slightly easier to do this outside of a class and with just a function and perhaps a static variable that holds the dataframe, e.g.,

import pandas as pd

# because I don't want the calling site to store df, I decided to keep it as a static variable here
def daily_csv_loader(filepath):
  daily_csv_loader.df = pd.read_csv(filepath)


def query(time, df):
  # return rows from df corresponding to time

with usage

import datetime

path = "/path/to/csv/file/filename.csv"
time = datetime.datetime(year=2020, month=1, day=1, hour=12, minute=2, second=0)
daily_csv_loader(filepath)
query(time, daily_csv_loader.)

Are there any other approaches here?

Problem with "define interface where it is used" principle in Golang

I am confused how to follow this rule in cases like this one. For example, I have some package with Criteria which use some kind of visitor

type Visitor interface {
    VisitID(int64)
    VisitLocation(lat, lon float64)
}

type CriteriaIdentity int64

func (c CriteriaIdentity) Apply(v Visitor) {
    v.VisitID(int64(c))
}

type CriteriaLocation struct {
   lat float64
   lon float64
}

func (c *CriteriaIdentity) Apply(v Visitor) {
    v.VisitLocation(c.lat, c.lon)
}

Then, I want to define a criteria interface in some package search:

type SearchCriteria interface {
     Apply(???) // What can I hint here?
}

type User struct {
    engine searchEngine
}

func (u *User) Search(ctx context.Context, criterias ...SearchCriteria) ([]int64, error) {
}

And use my searcher in some other package landing:

type Searcher interface {
    Search(ctx context.Context, criterias ...???) // Same question
}

How can I define hinting for SearchCriteria and `Se in a way that does not violate the rule?

Best practice on adding a new method in a class implementing an interface with less parameters required

public interface DataAdapter {

    int solve(int a, int b, int c)
}

Now i have multiple classes which implements this interface something like :

public class DataAdapterImplA implements DataAdapter {

    int solve(int a, int b, int c) {

        return ...
    }
}

public class DataAdapterImplB implements DataAdapter {

    int solve(int a, int b, int c) {

        return ...
    }
}

and similarly multiple others ...

Now i am adding one more implementing class but with one less parameter in the existing method signature ..something like below :

public class DataAdapterImplF implements DataAdapter {

    int solve(int a, int b) {

        return ...
    }
}

So , question here is how to go about this :

  1. Should i override the existing solve(int, int, int) method only & in my method body i can ignore this and won't use it at all ?

  2. should i create a default method solve(int, int) in the interface & override that in my new implementation class ?

or any other better & clean solution ?

What are the recommended design patterns for building scalable and maintainable software in Java? [closed]

Discover the recommended design patterns for building scalable and maintainable software in Java. Learn how these patterns, including Singleton, Factory, Builder, Observer, Strategy, Proxy, and Decorator, can enhance your Java development. These patterns promote code modularity, reusability, and flexibility, resulting in robust and easily maintainable systems.

Design patterns are proven solutions to recurring design problems, offering developers a set of best practices and guidelines. In the context of building scalable and maintainable software, certain design patterns have proven particularly useful. This question aims to identify these patterns and provide insights into their practical application within a Java development environment.

mardi 16 mai 2023

DDD Pattern - Repository and Service concerns

I am working on a modern DDD pattern since a few days (.NET + EF Core) and I have a bit of an hard time to figure how to use correctly a service layer.

I do understand that repositories are there for CRUD related operation and services for more complex logic (like involving multiple entities).

Let say for User entity, all CRUD operation should go into a UserRepository. But things like authentification, access rights, should belong to a service.

So my question is, should the service shallow the repository and expose CRUD operation through it. Or the application should simply use service or directly repository when needed ?

Also, it's easy to understand why the repositories interfaces should go in the domain and theirs implementations in the infrastructure. But what about services ? Some operation are totally related to business logic but some of them are more dependent on the infrastructure.

Could an UserService exist in different area ? Like in the domain and in the infrastructure ?

Thank for your help.

lundi 15 mai 2023

What is a good design pattern for a Java Swing application with long calculations in EDT?

I aw writing a chess game application using Java Swing. My game logic is obviously turn-based. Here is a very simplified excerpt:

public class PanelBoard extends JPanel implements MouseListener
{
    @Override
    public void paintComponent(Graphics g)
    {
        //Painting the board.
        //Painting chess pieces.
    }
    @Override
    public void mouseReleased(MouseEvent e)
    {
        //Calculate selected coordinates on the board.
        //If a chess piece is selected, highlight this piece and its possible moves.
        //If a destination is selected, nove a chess piece.
        //Repaint the board.
    }
}

I have recently discovered that all Java Swing components should be accessed on Event Dispatch Thread. But it is also said that all event handling should be as short as possible in order not to block the GUI. My questions are:

  1. Let's imagine that my calculation of all possible moves of a chess piece is a very long operation. Then in the mouseReleased() method I can call SwingWorker.doInBackground() method to make a separate thread for my long calculation. But is this really necessary in my case with a turn-based approach? User input is not expected until the previous event has been handled.

  2. In what cases making a background thread to handle a long calculation is a viable strategy?

  3. If I understand correctly, there are currently two threads in my program: main thread and EDT. Why make a separate background thread to handle a long calculation if this calculation can be redirected to a main thread?

  4. How exactly can I redirect a long calculation to a main thread and what design pattern can be used in such case? I come from an embedded world, so the only thing that comes to my mind is a polling architecture. Let's say, for example, a main thread has an infinite loop that waits for a particular event in a queue. In my case it would be a request to process a long calculation from mouseReleased() method (delayed interrupt/event processing). But this way my main thread becomes a copy of EDT and practically does the same thing. Also I beleive this approach defeats the whole purpose of event-driven architecture.

  5. What are good design patterns for GUI applications in general?

Identify text pattern in R dataframe

I have identifiers in two columns of a dataframe but with different structure. It looks like this:

  Description1                Description2
1  A0A2H1CVW1_FASHEprotein1   tr|A0A2H1CVW1|A0A2H1CVW1_FASHEprotein1 
2  A0A4E0RAA2_FASHEprotein2   tr|A0A2H1BSG1|A0A2H1BSG1_FASHEprotein3
3  A0A2H1CFJ4_FASHEprotein4   tr|A0A2H1CFJ4|A0A2H1CFJ4_FASHEprotein4

How could I identify the different identifiers between the two column, for example in row 2?

Validation should stop with the first condition violation

I have specification and I want to stop validation with first false result.

at now check all validation and then return result.

ISpecification:

 public interface ISpecification<T>
    {
        SpecificationResult IsSatisfiedBy(T value);
    }

Specification:

public abstract class Specification<T> : ISpecification<T>
{
    public Specification<T> And(ISpecification<T> right)
    {
        return new AndSpecification<T>(this, right);
    }
    public Specification<T> Or(ISpecification<T> right)
    {
        return new OrSpecification<T>(this, right);
    }
    public Specification<T> Not()
    {
        return new NotSpecification<T>(this);
    }

    public abstract SpecificationResult IsSatisfiedBy(T entity);
}

AndSpecification

    public class AndSpecification<T> : Specification<T>
{
    private readonly ISpecification<T> _leftSpec;
    private readonly ISpecification<T> _rightSpec;
    public AndSpecification(ISpecification<T> leftSpec, ISpecification<T> rightSpec)
    {
        _leftSpec = leftSpec;
        _rightSpec = rightSpec;
    }
    public override SpecificationResult IsSatisfiedBy(T entity)
    {
        return new SpecificationResult()
        {
            IsSatisfied = _leftSpec.IsSatisfiedBy(entity).IsSatisfied && _rightSpec.IsSatisfiedBy(entity).IsSatisfied,
            Message = new StringBuilder().Append(_leftSpec.IsSatisfiedBy(entity).Message).Append(_rightSpec.IsSatisfiedBy(entity).Message).ToString(),
        };
    }
}

my custom validation :

    public class UserIsActive : Specification<User>
{
    public override SpecificationResult IsSatisfiedBy(User user)
    {
        if (user.Status != UserStatus.Active)
        {
            return new SpecificationResult
            {
                IsSatisfied = false,
                Message = "حساب کاربری  شما غیرفعال میباشد لطفا با پشتیبانی تماس بگیرید"
            };
        }
        return new SpecificationResult
        {
            IsSatisfied = true,
            Message = string.Empty
        };
    }
}

public class UserIsNotExpoire : Specification<User>
{
    public override SpecificationResult IsSatisfiedBy(User user)
    {
        if (user.IsExpired)
        {
            return new SpecificationResult
            {
                IsSatisfied = false,
                Message = "حساب کاربری  شما منقضی شده است لطفا با پشتیبانی تماس بگیرید"
            };
        }
        return new SpecificationResult
        {
            IsSatisfied = true,
            Message = string.Empty
        };
    }
}

public class UserIsNotNull : Specification<User>
{
    public override SpecificationResult IsSatisfiedBy(User user)
    {
        if (user==null)
        {
            return new SpecificationResult
            {
                IsSatisfied = false,
                Message = "نام کاربری یا کلمه عبور اشتباه است"
            };
        }
        return new SpecificationResult
        {
            IsSatisfied = true,
            Message = string.Empty
        };
    }
}

and this how I use specification.

var validation = new UserIsActive().And(new UserIsNotExpoire().And(new UserIsNotNull()));

           var result = validation.IsSatisfiedBy(user);
            if (!result.IsSatisfied)
                return Ok(new
                {
                    success = false,
                    errorMessage = result.Message,  
                });

dimanche 14 mai 2023

C# Two GraphServiceClient singleton instances

In my application (.NET Web API), I need to call Microsoft Graph API using two different credentials set (completely different tenant). When I was using only one, the case was simple - I just did a setup in DI part of Program.cs:

var clientSecretCredential = new ClientSecretCredential(b2cSettings.TenantId, b2cSettings.ClientId, b2cSettings.ClientSecret, tokenCredentialOptions);

// Use a single client instance for the lifetime of the application
services.AddSingleton(sp =>
{
    return new GraphServiceClient(clientSecretCredential, new[] { "https://graph.microsoft.com/.default" });
});

which allowed me to just inject it to whichever service I needed, like so:

    public GraphApiClient(
        GraphServiceClient graphServiceClient)
    {
        _graphServiceClient = graphServiceClient;
    }

Obviously, there is no way to re-use that for second set of credentials - it will just pick the last registered GraphServiceClient instance.

It smells like some common pattern, but it does not seem to be a good candidate for factory (I want only TWO instances across app lifetime - each with different credentials). I also wonder how would service "client" (class using it) specify which GraphServiceClient to retrieve in runtime.

I imagine some "aggregate" class with methods like:

RegisterGraphApiClientWithCredentials(string tenantId, string clientId, string clientSecret); // <- this would be done once, in Program.cs

RetrieveGraphApiClientWithCredentials(string tenantId, string clientId, string clientSecret); // <- this would be done whenever some service would need actual client instance

How should I approach this problem? Microsoft advise single instance for the lifetime of the application. Will this approach collide with that?

Thank You in advance!

How to keep loaded entities in memory in .net and ef

So, I am working on a legacy application written in .NET 2.0 and C# that's only purpose is to execute workflows (background jobs or processes). In essence what it does is:

  1. On app startup it loads all objects from DB into memory (in classes called Holder)
  2. Start the processes (multiple of them) each in its own thread
  3. These processes works on the data in memory (multi-threaded) so the data access is kept between locks. The process of retrieving and updating the data

So the above picture depicts the process to work with the data.

I have the task to modernize this using new .NET 7 + Entity Framework and its capabilities. Because this application is heavily multi-threaded and many of the infrastructure classes like (workers, holders, dal access) are singletons there is locking everywhere.

My wishes are this:

  1. Because of multiple threads accessing the same data, I would like to get rid of those singletons. But the problem for me is where should I keep the in memory data the workflow needs to work with it.?
  2. If I choose to not remove singletons, then I was thinking to use Repository pattern to hold the entities in memory, but then I they should be singletons any I don't know if this is a good idea.

So my problem is where to keep the data once is loaded so that many threads can use (read, update delete) it without going into DB each time?

I need a design pattern for this, or maybe use some sort of Level2 cache for Entity Framework

Deleting dynamic_cast'ed pointer with multiple interfaces

I am trying to delete a dynamic_cast pointer which has multiple interfaces as shown in below program. By doing delete sb; , I am hoping to delete only resources of B, not other classes, but in my case it is deleting the other classes also.

Result:

   Inside B
   delete C
   delete B
   delete A
#include <iostream>
using namespace std;

enum ObjType {At =0, Bt, Ct};

//Interface A
struct A{
    virtual void do_A() = 0;
    virtual ~A(){
        cout<<"delete A"<<endl;
    }
};

//Interface B
struct B{
    virtual void do_B() = 0;
    virtual ~B(){
        cout<<"delete B"<<endl;
    }
};

//Interface C
struct C{
    virtual void do_C() = 0;
    virtual ~C(){
       cout<<"delete C"<<endl; 
    }
};

//Factory Server
struct FactoryServer: A, B, C
{
    void do_A(){
       cout<<"Inside A"<<endl;
    }
    void do_B(){
       cout<<"Inside B"<<endl;
    }
    void do_C(){
       cout<<"Inside C"<<endl;
    }
    
    static  FactoryServer* create(){
        return new FactoryServer();
    }

};

B* clientB(){
    return dynamic_cast<B*>(FactoryServer::create());
}

void clientAB(){
     
}

void clientBC(){
    
}

void clientCA(){
    
}

void clientABC(){
    
}

//client is allowed to takes services of any of A, B, and C or all of or some of 
int main(){
    
    B *sb = clientB();
    sb->do_B();
    delete sb;
    return 0;
}

Instead of deriving from all three interfaces, I can derive separately as required from any of, all of or some of interfaces, but that defeats the purpose of Factory.

I am not much familiar with Design Patterns, but in general how is the clean-up done in the scenarios like these.

samedi 13 mai 2023

Design pattern for implementing policy card system like Civilization 6

I am an amateur Unity game developer working on a game that features a policy card system similar to Civilization 6. Currently, my code feels difficult to extend and I'm not sure which design pattern would be best suited for this feature.

However, I'm worried that this approach might not be scalable as more policy cards are added to the game. What design pattern should I use to make the system more flexible and easy to extend? How can I implement it in Unity? Any code examples or resources would be greatly appreciated.

Thank you in advance for your help!

Regarding the interference of policy cards with other systems, I tried to use the observer pattern. I let other systems register for events from the policy card system. Every time a policy card is mounted, the event is broadcasted. However, I encountered some issues with handling numerical values. For example, if I want a certain policy card to increase the HP of a unit, I found that my current code is a mess.

Unable to wrap my head around the implementation of Mediator pattern

I am trying to learn Design patterns using OOP by building a game.

The game will have a predator and a prey. When a predator comes near the prey, it starts eating it. Until now, I have come so far.

I think I will need a mediator pattern here as there will be one alien (predator) and multiple humans (preys) walking on a given area of the game. The area being the mediator.

I won't be going in to the graphics part yet, but I just want to run on the command line like human1.reduceHP() that will reduce human1's HP. But, the condition for this code to happen is missing (I believe in the form of the Mediator).

However, I am unable to wrap my head around the actual implementation. I have come this far with the following:

  1. Organism as the base class and IEatable as interface.
  2. Human and Alien are the concrete implementations of the Organism.
  3. Human is IEatable.
export abstract class Organism {
  abstract maxHP: number;
  abstract currentHP: number;
  abstract canHit: boolean;

  isStomachFull = false;
  stomachCapacity = 100;

  reduceHp() {
    if (this.currentHP > 0) {
      this.currentHP -= 1;
    }
  }

  recoverHp() {
    if (this.maxHP < this.currentHP) {
      this.currentHP += 1;
    }
  }
}
interface IEatable {
  isEatable: boolean;
}
import { Organism } from '../abstract/Organism';

export class Alien extends Organism {
  maxHP: number;
  currentHP: number;
  canHit: boolean;

  constructor(hp, canHit) {
    super();
    this.maxHP = hp;
    this.canHit = canHit;
    this.currentHP = this.maxHP;
  }
}
import { Organism } from '../abstract/Organism';

export class Human extends Organism implements IEatable {
  maxHP: number;
  currentHP: number;
  canHit: boolean;
  isStomachFull: boolean;
  stomachCapacity: number;
  isEatable: boolean;

  constructor(hp, canHit, isEatable) {
    super();
    this.maxHP = hp;
    this.canHit = canHit;
    this.currentHP = this.maxHP;
    this.isEatable = isEatable;
  }
}

jeudi 11 mai 2023

Adding a new attribute in Request object using lombok Builder

Background

I want to add one more attribute TemplateId to the Request object. Currently the Request object is constructed in the function transform using builder like below:

public class DocFactory { 

ModuleProvider<Collection<Scenario>> dollarScenarioProvider;

public Request transform(String requestId, Product product) {
    Request.RequestBuilder.builder = Request.builder();

    BiFunction<Throwable, Runnable, Throwable> handler = (e, runnable) -> {
       if (e == null) {
          runnable.run();
          return null;
       } else {
          Log.error ("Failed to process DocumentRequestModule(())", requestId, e.getCause);
          return e.getCause);

    String errorMessage = Stream.of(dollarScenarioProvider.getAsync(product)
                         .handle((result, e) -> handler.apply(e, () ->                                                             
                           builder.scenarioDollar(result)))))
                                .map(CompletableFuture::join)
                                .filter(Objects::nonNull)
                                .map(Throwable::getMessage)
                                ...
}}

For the getAsync method in ModuleProvider, it's defined like so:

public interface ModuleProvider<R> {

default CompletableFuture<R> getAsync (Product product) {
     return CompletableFuture.completedFuture(get(product));
}

//other methods omitted

My questions:

  1. The attribute I want to add in Request is TemplateId, which is a string. This string will be returned by a function getTemplateId (which takes in the argument Product product and returns a String). It seems like maybe I should do something like:
TemplateIdProvider.getAsync(product)
                         .handle((result, e) -> handler.apply(e, () ->                                                             
                           builder.TemplateId(result)))))

But where should I put the function getTemplateId?

  1. I don't exactly understand what this code is doing. Is it related to Factory Pattern? I know the code that I shared is trying to construct a Request using builder, but the way is it done (using handler & ModuleProvider, ... seems obscure to me , could you please share with me your insight on why it would be done this way?
TemplateIdProvider.getAsync(product)
                         .handle((result, e) -> handler.apply(e, () ->                                                             
                           builder.TemplateId(result)))))

Thank you so much in advance.

Versioning for child class implementation after factory design pattern

I got in to a design problem where I have different implementation for saving the data and processing other things for the different tools. I used a factory design for saving the data and same in getting the data from the database.

class SaveDataService {
  public void saveData(Data data) {
  }

  public List<Tool> getTools() {
    return List.of();
  }
}

class FishToolSaveDataService extends SaveDataService {
  @Override
  public void saveData(Data data) {
  }

  @Override
  public List<Tool> getTools() {
    return List.of(Tool.FISH);
  }
}

class DogSaveDataService extends SaveDataService {
  @Override
  public void saveData(Data data) {
  }

  @Override
  public List<Tool> getTools() {
    return List.of(Tool.DOG);
  }
}
class Data {
  JsonNode data;
  int version;
}

enum Tool {
  FISH,
  DOG
}

So, My Factory mapper is based on the enum Tool

Now I have a version for each tool to maintain but the saving implementation changes for each version. How do I maintain this without using if else checks in the saveData(Data data) method implementation.

I tried simple if/else check for version the saveData method but it will prolonged to long if I have five different version and two different tools have same logic of saving for the different version. That is duplicating my code.

How can I design this version such that I can reuse my code?

I have 15 tools implementation in to total and I am starting with the version 2 of 3 tools in total but in future more versioning and more tools will come.

How to improve performance/design on this Blazor "excel-like" application?

I am developing a Blazor server application to replace Excel sheets that perform various calculations. Instead of a large grid containing all the cells, I am using a few Razor components with HTML tables, and the cells contain text inputs. The formulas for each cell are stored in a database using a format that is parseable through the FLEE library (expression evaluator).

During application startup, I retrieve all formulas from the database into memory, which is stored as a List of objects. Then, each cell input is value-bound to a property in my form class whose getter and setter interact with the List of formulas through a function.

Using Blazor's own lifecycle, every time the content is refreshed, the cell's input @bind attribute calls the property getter, which calls a function to retrieve the value associated with that cell's name. The function performs several string operations and finally evaluates the formula using FLEE to obtain the final value, which is displayed in the input.

However, I have encountered two problems. Firstly, as the formulas become more complex and the forms grow in size, the application's performance slows down significantly. Secondly, while the final value is being evaluated, I can interact with my Blazor page, but it only performs the desired action after many "refresh cycles" - for example, I click a button, but only after several seconds of calculations, the button action is called.

Now I will provide code snippets showing the application workflow

How formulas are store in DB:


| PropertyName | Value                 |
| ------------ | --------------------- |
| BMI          | = @Weight / @Height^2 |
| Height       |                       |
| Weight       |                       |

My razor page, containing the cells:

<EditForm Model=@BodyMeasurements>
    <div class="container form">
        <table class="table table-hover">
            <tbody>
                <tr>
                    <td>
                         <input type="text" class="form-control @bind=Weight>
                    </td>
                    <td>
                         <input type="text" class="form-control @bind=Height>
                    </td>
                    <td>
                         <input type="text" class="form-control @bind=BMI readonly>
                    </td>
                </tr>
            </tbody>
        </table class="table table-hover">
    </div>
</EditForm>

My form model

using System.Globalization;

namespace FitApp.Models.BodyMeasurements
{
    public class BodyMeasurements
    {
        private readonly Calculator calc;

        public BodyMeasurements(Calc calc)
        {
            this.calc = calc;
        }

        public string? Weight
        {
            get
            {
                return calc.RetrieveValue("UserWeight");
            }
            set
            {
                calc.SetValue("UserWeight", value);
            }
        }
        
        public string? Height
        {
            get
            {
                return calc.RetrieveValue("UserHeight");
            }
            set
            {
                calc.SetValue("UserHeight", value);
            }
        }
        
        public string? BMI
        {
            get
            {
                return calc.RetrieveValue("BMI");
            }
            set
            {
                return;
            }
        }
    }
}

My Calculator class

using FitApp.Models;

namespace FitApp.Models.BodyMeasurements
{
    public class Calculator
    {
        public readonly List<UserAttributes> userAttributes;

        public DadosProposta(IEnumerable<UserAttributes> userAttributes)
        {
            // Recebo os dados
            this.userAttributes = userAttributes.ToList();
        }

        public void SetValue(string propertyName, object newValue)
        {
            foreach (var result in userAttributes.Where(r => r.PropertyName == propertyName))
            {
                result.Value = Convert.ToString(newValue);
                break;
            }
        }

        public string RetrieveValue(string propertyName)
        {
            try
            {
                // Search for the attribute in the list
                UserAttributes result = userAttributes.FirstOrDefault(r => r.PropertyName == propertyName);

                // If not found, or null Value, returns null
                if (result is null || string.IsNullOrEmpty(result.Value))
                {
                    return null;
                }

                // If value is not a formula, returns Value
                if (IsNotFormula(result.Value))
                {
                    return result.Value.Trim();
                }

                // Takes the formula as is
                string originalFormula = result.Value.Trim();

                // Simplifies the formula's IFs, if necessary, to reduce its size and execution time
                string simplifiedFormula = SimplifyIF(originalFormula).Item1;

                // Replaces the remaining references and VLOOKUPs with the values
                string replacedFormula = simplifiedFormula;

                while (replacedFormula is not null && (replacedFormula.Contains("VLOOKUPs") || replacedFormula.Contains('@')))
                {
                    // Replaces references with numeric values
                    replacedFormula = TreatVLOOKUP(replacedFormula);
                    replacedFormula = ReplaceReferences(replacedFormula).GetAwaiter().GetResult();
                }

                string finalValue = "";

                // In case the translated formula is not yet in the table, or it is different in the library
                if (!string.IsNullOrEmpty(replacedFormula) && (result.TranslatedValue is null || result.TranslatedValue != replacedFormula))
                {
                    // Get the field index in the library
                    var index = userAttributes.IndexOf(result);

                    // Stores the processed formula in the TranslatedValue column of the library
                    userAttributes[index].TranslatedValue = replacedFormula;

                    // Solves the formula
                    finalValue = SolveFormula(replacedFormula).GetAwaiter().GetResult();

                    // Updates the value in the library -- if it returns null, I leave it blank, so that null values are not calculated repeatedly
                    userAttributes[index].EvaluatedValue = finalValue ?? string.Empty;
                }
                else
                {
                    // If already evaluated
                    finalValue = result.EvaluatedValue;
                }

                return finalValue;
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
                return string.Empty;
            }
        }

        private async Task<string> ReplaceReferences(string formula)
        {
            // If there is still a reference
            if (formula is not null && formula.Contains('@'))
            {
                // Iinitialize the list
                List<string> references = new();

                // Scans the text, looking for references
                foreach (var item in formula.Trim().Split('@'))
                {
                    string name = string.Empty;

                    // Remove non-alphanumeric characters from substring
                    for (int i = 0; i < item.Length; i++)
                    {
                        if (char.IsLetterOrDigit(item[i]))
                        {
                            name += string.Concat(item[i]);
                        }
                        else
                        {
                            break;
                        }
                    }

                    // I add it only once, to avoid repeated queries
                    if (!references.Contains(name) && !string.IsNullOrEmpty(name))
                    {
                        references.Add(name);
                    }
                }

                // Sort the list, in descending order, by the number of characters
                references.Sort((a, b) => b.Length.CompareTo(a.Length));

                // If any found
                if (references.Count > 0)
                {
                    // Get the attribute
                    UserAttributes result = userAttributes.FirstOrDefault(d => d.PropertyName == references[0]) ?? null;

                    // If not found
                    if (result == null)
                    {
                        return null;
                    }
                    else
                    {
                        // Treat the value if it is empty
                        string value = string.IsNullOrEmpty(result.Valor) ? "0" : result.Valor;

                        // If it is a simple formula, without reference or VLOOKUP, proceeds to evaluation
                        if (!value.Contains('@') && !value.Contains("VLOOKUP", StringComparison.CurrentCultureIgnoreCase) && value.Contains('='))
                        {
                            value = await SolveFormula(value);
                        }

                        // Try and simplify IF
                        if (FormulaHasIF(value))
                        {
                            value = SimplifyIF(value).Item1;
                        }

                        // Removes the '=' symbol from the beginning, if necessary
                        if (value is not null && value.Trim().StartsWith('='))
                        {
                            value = value.Trim().Remove(0, 1);
                        }
                            
                        if (!(string.IsNullOrEmpty(result.EvaluatedValue)))
                        {
                            formula = formula.Replace($"@{references[0]}", $"({result.EvaluatedValue,})");
                        }
                        else
                        {
                            // Replace with value in text -- wrap new value with ( ) to correctly handle IFs within IFs
                            formula = formula.Replace($"@{references[0]}", $"({value})");
                        }
                    }
                }
            }

            return formula;
        }

        private async Task<string> SolveFormula(string formula)
        {
            if (string.IsNullOrEmpty(formula))
            {
                return null;
            }
            else
            {
                while (formula is not null && (formula.Contains("VLOOKUPs") || formula.Contains('@')))
                {
                    // Replaces references with numeric values
                    formula = TreatVLOOKUP(formula);
                    formula = ReplaceReferences(formula).GetAwaiter().GetResult();
                }

                // Simplifies the formula's IFs, if necessary, to reduce its size and execution time
                formula = SimplifyIF(originalFormula).Item1;

                if (formula is null)
                {
                    return null;
                }

                // Remove '=' from the start
                if (formula.IndexOf('=') > -1 && formula.IndexOf('=') < 3)
                    formula = formula.Remove(formula.IndexOf('='), 1).Trim();

                // Solves
                var result = FLEE.Eval(formula);

                // Returns
                return result;
            }
        }
    }
}

FLEE implementation

using Flee.PublicTypes;
using System.Globalization;

namespace FitApp.Models
{
    public static class Equacoes
    {
        static ExpressionContext context;
        
        static Equacoes()
        {
            // Flee context
            context = new ExpressionContext();
            context.Options.ParseCulture = new CultureInfo("pt-BR");
            context.ParserOptions.FunctionArgumentSeparator = ';';
            context.ParserOptions.RecreateParser();
            context.Options.RealLiteralDataType = RealLiteralDataType.Double;

            // Allow the expression to use all static public methods of System.Math
            context.Imports.AddType(typeof(Math));
        }

        public static string Eval(string expression)
        {
            try
            {
                Flee.PublicTypes.IDynamicExpression eDynamic = context.CompileDynamic(expression);

                // Calcula
                var result = eDynamic.Evaluate();
                return Convert.ToString(result) == "NaN" ? null : Convert.ToString(result);
            }
            catch (ExpressionCompileException)
            {
                return null;
            }
            catch (Exception)
            {
                return null;
            }
        }
    }
}

In this example (sorry if it will no compile, had to ommit some parts due to company policies), in order to display BMI, the user must fill Weight and Height. Then, @bind attribute in the BMI input will call the function RetrieveValue through the getter. The RetrieveValue function will get the field formula in the list, replace @Height and @Weight for its corresponding values, and then send the "translated" formula to the evalution library.

This example is pretty simple, and would work with no problems, but there are much more complex formulas in my system, which generates string with thousands of characters (imagine an expression with 25k characters, due to excel design of linking cells). Solving these big expressions is not the slowest part, but actually working with the string, replacing references with the correct values, which can take from 200ms to 4000ms

I tried string operations to reduce complexity of formula sent to the evaluation lib, but then realized it's not the bottleneck, its actually when I'm working with the strings.

Also, tried to using different Render methods on Blazor lifecycle (like OnAfterRender), so user could at least see the form while the values are dinamically being loaded, but did not work

mercredi 10 mai 2023

Swift Architectural Problem with Protocol and Inheritance

I’m more familiar with C++ than i am with Swift, but I’m struggling with getting the architecture right for my problem.

The App Delegate talks to my custom ‘MenuSystem’ singleton and says ‘load the app storyboard and make key&visible’ and all that good stuff.

However, the type of menu that the ‘MenuSystem’ class will use will vary by device. i.e. on iPhone - just as an example - it could be a drawer type menu, but on iPad it might be a tab bar and on macOS it might be a tool bar or side menu…

So the menu system class has a property called ‘menuController’ and there is a custom protocol that all the actual subclassed View Controllers (i.e. uitableview for drawer, uitabviewcontroller for tab bar etc etc etc)

This protocol defines all the common things that the ‘MenuSystem’ class needs to communicate to the actual, in use, menu.

The protocol is called ‘RootMenuProtocol’

Each of these will be implemented by an actual class e.g. a subclass of UITableViewController that conforms to the ‘RootMenuProtocol’ protocol.

So in the MenuSystem singleton, I need the property ‘self.menuController’ to refer to any one of the 3 possible (or more) classes that conform to the protocol.

The problem with this architecture is that when I try and then assign the type of UIViewController currently assigned to the property ‘self.menuController’ to ‘rootWindow?.rootViewController’ I get an error : Cannot assign value of type '(any RootMenuProtocol)?' to type 'UIViewController?'

Here's the code:

App Delegate

import UIKit

@main class AppDelegate: UIResponder, UIApplicationDelegate
{
  var window: UIWindow?

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
  {
    // Override point for customization after application launch.
    
    // Create Menu system and launch first view controller
    MenuSystem.shared.loadInitialViewControllerAndMakeActiveInto(Window: window, UsingApplicationStoryboardWithName: "Main")
    
    return true
  }
}

RootMenuProtocol

import Foundation

protocol RootMenuProtocol
{
  func transitionTo(StoryboardID: Any, UsingCustomAnimationTransition: Any)
}

MenuSystem Singleton

import Foundation
import UIKit

class MenuSystem
{
  static let shared: MenuSystem = MenuSystem()
  private var menuController: RootMenuProtocol?
    
  private init()
  {
  }
    
  internal func loadInitialViewControllerAndMakeActiveInto(Window rootWindow: UIWindow?, UsingApplicationStoryboardWithName applicationStoryboardName: String)
  {
    if UIDevice.current.userInterfaceIdiom == .phone
    {
      self.menuController = UIStoryboard(name: "PBFMenuSystem", bundle: nil).instantiateViewController(withIdentifier: "drawerRootViewController") as? MenuRootTableViewController
      
      rootWindow?.rootViewController = self.menuController
      rootWindow?.makeKeyAndVisible()
    }
    else if UIDevice.current.userInterfaceIdiom == .pad
    {
      self.menuController = UIStoryboard(name: "PBFMenuSystem", bundle: nil).instantiateViewController(withIdentifier: "tabBarRootViewController") as? MenuRootTabBarViewController
      
      rootWindow?.rootViewController = self.menuController
      rootWindow?.makeKeyAndVisible()
    }
    else if UIDevice.current.userInterfaceIdiom == .mac
    {
      // Tool Bar here...
    }
  }
  
  internal func requestTransitionTo(StoryboardID id: String, UsingCustomAnimationTransition transitionAnimation: UIViewControllerAnimatedTransitioning? = nil)
  {
    self.menuController?.transitionTo(StoryboardID: id, UsingCustomAnimationTransition: transitionAnimation as Any)
  }
}

MenuRootTabBarViewController

import UIKit

class MenuRootTabBarViewController: UITabBarController, RootMenuProtocol
{
  
  override func viewDidLoad()
  {
    super.viewDidLoad()
    
    // Do any additional setup after loading the view.
  }
  
  func transitionTo(StoryboardID: Any, UsingCustomAnimationTransition: Any)
  {
  }
}

MenuRootTableViewController

import UIKit

class MenuRootTableViewController: UITableViewController, RootMenuProtocol
{
  
  override func viewDidLoad()
  {
    super.viewDidLoad()
    
  }
  
  func transitionTo(StoryboardID: Any, UsingCustomAnimationTransition: Any)
  {
  }
  
  // MARK: - Table view data source
  
  override func numberOfSections(in tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 0
  }
  
  override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows
    return 0
  }
}

Can someone show me what I've misunderstood about Swift architecture and inheritance/protocols?

I just want the property 'self.menuController' to point to whichever UIViewController subclass I've got that also musts conform to the 'RootMenuProtocol'.