lundi 5 juin 2023

Service Class with Multiple Repositories

class AccountClosureService(
    private val accountClosureRepository: AccountClosureRepository,
    private val userApplicationRepository: UserApplicationRepository,
){ 
// CRUD METHODS 
}

interface AccountClosureRepository{}

@Component
private class AccountClosureRepositoryImpl(): AccountClosureRepository
{}


interface UserApplicationRepository{}

@Component
private class UserApplicationRepositoryImpl():UserApplicationRepository
{}

I doesn't look fine to inject UserApplicationRepository in AccountClosureService as both Entities is different.

Not sure if we have a better way to implement above Class Design.

Checked RepositoryDesignPattern but no solution found for this case.

Any suggestions would be appreciated !!

benefit of initialising an object using proxy method?

I was going through fastapi source code and there I saw param_functions file.

def Path(  # noqa: N802
    default: Any = Undefined,
    *,
    alias: Optional[str] = None,
    title: Optional[str] = None,
    description: Optional[str] = None,
    gt: Optional[float] = None,
    ge: Optional[float] = None,
    lt: Optional[float] = None,
    le: Optional[float] = None,
    min_length: Optional[int] = None,
    max_length: Optional[int] = None,
    regex: Optional[str] = None,
    example: Any = Undefined,
    examples: Optional[Dict[str, Any]] = None,
    deprecated: Optional[bool] = None,
    include_in_schema: bool = True,
    **extra: Any,
) -> Any:
    return params.Path(
        default=default,
        alias=alias,
        title=title,
        description=description,
        gt=gt,
        ge=ge,
        lt=lt,
        le=le,
        min_length=min_length,
        max_length=max_length,
        regex=regex,
        example=example,
        examples=examples,
        deprecated=deprecated,
        include_in_schema=include_in_schema,
        **extra,
    )

Ultimately they are forwarding their calls to Path class initialiser. My question is why are they doing it like this? and why not simply use the class instead of calling a method which calls the class initialiser, why not directly initialise the class.

dimanche 4 juin 2023

Which of the software design patterns does this code implement [closed]

From what we can tell, it implements bridge pattern, facade pattern and SOLID principles (of which)?

from abc import ABC, abstractmethod
from codesearchMy.utils.lang_model_utils import load_lm_vocab, Query2Emb
from codesearchMy.classes.searchengine import mytoolSearchEngine, mytoolConfig
#from codesearchNokia.nokiasearchengine import model_config

import nmslib
from pathlib import Path
import numpy as np
import pandas as pd
import torch
import nmslib

class searchEngine(ABC):
    def __init__ (self, nmsIndex):
        self.name = "Search Engine Framework"
        self.nmsIndex = nmsIndex
        
    @abstractmethod
    def search(self):
        pass

class myTool(searchEngine):
    def __init__(self, nmsIndex):
        super().__init__(nmslib.init(method='hnsw', space='cosinesimil'))
        self.nmsIndex.loadIndex('./codesearchMy/data/search/search_index.nmslib')
        self.config = mytoolConfig()
        self.q2emb = Query2Emb(lang_model = self.config.lang_model.cpu(), vocab = self.config.vocab)
        self.ref_df = pd.concat([self.config.url_df, self.config.code_df], axis = 1).reset_index(drop=True)
        
        self.engine = mytoolSearchEngine(nmslib_index=self.nmsIndex, ref_df=self.ref_df, query2emb_func=self.q2emb.emb_mean)
    
    
    def search(self, query):
        self.engine.search(query)
        
class nokiaSearchTool(searchEngine):
    def __init__(self, retrieval_model):
        self.retrieval = retrieval_model
    def search(self, query):
        retrieval_model.query(query)
        
        
queryS = input("Enter query to search: ")
        
tools = [myTool(nmslib.init(method='hnsw', space='cosinesimil'))]  #nokiaSearchTool()
for tool in tools:
    tool.search(queryS)
    
    

How to design a low-level system using OOP principles to notify users when a previously out-of-stock product becomes available? [closed]

Design a system where if a user want to buy a product that is out of stock then notify the user when product is back in stock.

I tried to implement it following way in C++. Please provide any improvements or any other solution for the problem. Please provide some improvements in term of using data structure or passing arguments.

#include <bits/stdc++.h>
using namespace std;

class User
{
public:
    void sendNotification(string prodName)
    {
        cout << prodName << " Product is Available" << endl;
    }

    void bought(string prodName)
    {
        cout << "Bougth product " << prodName << endl;
    }

    void productNotAvailable(string prodName)
    {
        cout << prodName << " Product is currently out of stock, We will notify you when it will be available." << endl;
    }
};

class Product
{
public:
    int qnt;
    string prodName;
    queue<User> q;

    Product(int qnt, string prodName)
    {
        this->qnt = qnt;
        this->prodName = prodName;
    }

    void notify(User u)
    {
        u.sendNotification(prodName);
    }

    void addProduct(int newQnt)
    {
        if (qnt == 0)
        {
            while (!q.empty())
            {
                notify(q.front());
                q.pop();
            }
        }
        qnt += newQnt;
    }

    void buyProduct(User u)
    {
        if (qnt == 0)
        {
            q.push(u);
            u.productNotAvailable(prodName);
        }
        else
        {
            u.bought(prodName);
            qnt -= 1;
        }
    }
};

int main()
{
    Product iphone = Product(1, "Iphone");
    User u1 = User();
    User u2 = User();
    User u3 = User();

    iphone.buyProduct(u1);
    iphone.buyProduct(u2);
    iphone.buyProduct(u3);

    iphone.addProduct(10);
}

Is another way to write this APL pattern?

CONTEXT

let ns be an unsorted array of unique integers of arbitrary length, return the smallest missing positive number of that array. for example

ns = {-1, -3, -2} -> 1
ns = {1, 2, 3, 4, 5, 6, 7, 8, 9} -> 10
ns = {-1, 5, 1} -> 2

I saw this on an APL youtube video and decided to give it a try myself, my solution is

smallestMissingPositive ← {⌊/(⍳⌈/⍪(1∘+)⌈/⍵)~⍵}

explanation:

  1. the ⍳⌈/⍪(1∘+)⌈/ part is is just all positive number up to N+1 where N is the greatest number in . Using a fork to concatenate ⍳⌈/ (a list of positive integers up to the greatest number in ) with (1∘+)⌈/ (the greatest number in plus 1)
  2. ~⍵ just takes the difference of the previous point to the original list
  3. ⌊/ then finally taking the minimum value on that list

so for ns = {-1, 1, 3, -2, 5} first we generate {1, 2, 3, 4, 5, 6} then take the difference of ns from that which is {2, 4, 6} then taking the minimum element which is 2.

QUESTION

Is there a way to optimize my solution further?

HUNCHES

  • I don't even know if my solution is correct or not (i.e. misses a corner case)
  • the max-reduce ⌈/ function is used twice in ⍳⌈/⍪(1∘+)⌈/. the 3-train fork turns fgh ⍵ into (f ⍵) g (h ⍵) but in this particular case the pattern is (h (f ⍵)) g (h' (f ⍵)) can remove the redundancy in f?

C++ OpenGL Why is only one image rendering?

Hello I am new to OpenGL and I am trying to learn it .
I am trying to create a way to load all the images which I plan to use in OpenGL and then render them all on the screen. It seems OpenGL seems to be very code repetitive in it's process of creating VAO,VBA, and EBOs.

I am a newbie at this , so please explain why this is only rendering one image? I thought the image object would be stored in the VAO.

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <vector>
#include "ogl_shaders.h"

const int MAX_TEXTURES = 255;
GLuint vaos[MAX_TEXTURES] = {0};
GLuint s_textures[MAX_TEXTURES] = {0};
int x_pos[] = {0, 300, 600};
int y_pox[] = {0, 100, 50};
int w_size[] = {200,200, 200};
int h_wize[] = {200, 200, 200};
std::vector<std::string> g_image_paths = { "image.png", "image2.png", "image3.png" };

struct Vec2 {
    float x;
    float y;
};

Vec2 toNDC(int pixel_x, int pixel_y, int window_width, int window_height) {
    Vec2 vec;
    vec.x = (static_cast<float>(pixel_x) / window_width) * 2.0f - 1.0f;
    vec.y = (static_cast<float>(pixel_y) / window_height) * 2.0f - 1.0f;
    return vec;
}

// I assume the problem is here  <<<
GLuint setupImageRectangle(int posX, int posY, int sizeX, int sizeY, GLuint shaderProgram, GLuint texture) {
    // Convert position to NDC
    Vec2 vec = toNDC(posX, posY, 800, 600);
    float ndcPosX = vec.x;
    float ndcPosY = vec.y;

    // Convert size to NDC
    float ndcSizeX = static_cast<float>(sizeX) / (800 / 2.0f);
    float ndcSizeY = static_cast<float>(sizeY) / (600 / 2.0f);

    // Vertex data for the rectangle
    float vertices[] = {
        ndcPosX, ndcPosY, 0.0f, 0.0f, // Bottom-left
        ndcPosX + ndcSizeX, ndcPosY, 1.0f, 0.0f, // Bottom-right
        ndcPosX + ndcSizeX, ndcPosY + ndcSizeY, 1.0f, 1.0f, // Top-right
        ndcPosX, ndcPosY + ndcSizeY, 0.0f, 1.0f  // Top-left
    };

    GLuint elements[] = {0, 1, 2, 2, 3, 0};

    // Create and bind the VAO
    GLuint vao;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    // Load the vertex data into a VBO
    GLuint vbo;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    // Load the element data into an EBO
    GLuint ebo;
    glGenBuffers(1, &ebo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);

    // Specify the layout of the vertex data
    GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
    glEnableVertexAttribArray(posAttrib);
    glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);

    GLint texAttrib = glGetAttribLocation(shaderProgram, "texcoord");
    glEnableVertexAttribArray(texAttrib);
    glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));

    // Bind the texture to the rectangle
    //glBindTexture(GL_TEXTURE_2D, texture);

    return vao;
}


void CreateTexture(std::vector<std::string> image_path) {
    for (int image = 0; image < image_path.size(); image++) {
        // Generate a texture ID
        glGenTextures(1, &s_textures[image]);
        
        // Bind the texture ID
        glBindTexture(GL_TEXTURE_2D, s_textures[image]);

        // Set texture parameters
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        // Load the image data
        int width, height, nrChannels;
        stbi_set_flip_vertically_on_load(true); // Flip image
        unsigned char* data = stbi_load(image_path[image].c_str(), &width, &height, &nrChannels, STBI_rgb_alpha); 
        
        if (data) {
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
            glGenerateMipmap(GL_TEXTURE_2D);
        } else {
            std::cout << "Failed to load texture: " << image_path[image] << std::endl;
        }

        // Free the image data
        stbi_image_free(data);
    }
}

void helper_gl_bindTextures(GLuint vaos[], int size) {
    
    for (int i = 0; i < size && vaos[i] != 0; i++){
        glActiveTexture(GL_TEXTURE0 + i); // activate the texture unit first before binding texture
        glBindTexture(GL_TEXTURE_2D, s_textures[i]);
        glBindVertexArray(vaos[i]);
        std::cout << "image of vaos loaded " << i << std::endl;
        
    }
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
}

int main()
{
    glfwInit();
    GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL", nullptr, nullptr);
    glfwMakeContextCurrent(window);
    glewInit();

    // Compile and activate shaders
    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexSource, nullptr);
    glCompileShader(vertexShader);
    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentSource, nullptr);
    glCompileShader(fragmentShader);
    GLuint shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
    glUseProgram(shaderProgram);



CreateTexture(g_image_paths);

for (int idx = 0 ; idx < g_image_paths.size(); idx++){
    vaos[idx] = setupImageRectangle(x_pos[idx], y_pox[idx], w_size[idx], h_wize[idx], shaderProgram, s_textures[idx]);
}
    while(!glfwWindowShouldClose(window))
    {
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        // Draw the texture on the screen
        helper_gl_bindTextures(vaos, sizeof(vaos) / sizeof(vaos[0]));
        
        // Swap buffers and poll window events
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    // Cleanup and exit
    for (int idx = 0 ; idx < sizeof(s_textures); idx++){
        glDeleteTextures(1, &s_textures[idx]);
    }
    
    glfwTerminate();
    return 0;
}

samedi 3 juin 2023

DTO to entity conversion: in service or controller, for manytoone owning side, should service accept DTO

Suppose I have a simple application with entities like these:

Dog.java:

@Entity(name = "dogs")
public class Dog  {
    @Id
    @SequenceGenerator(name = "dog_sequence",
                            sequenceName = "dog_sequence",
                            allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE,
                            generator = "dog_sequence")
    private Long id;
  
    @Column(unique = true)
    private String name;

    // getters, setters, constructors
}

Command.java:

@Entity(name = "commands")
public class Command  {
    @Id
    @SequenceGenerator(name = "command_sequence",
                            sequenceName = "command_sequence",
                            allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE,
                            generator = "command_sequence")
    private Long id;
  
    @Column(unique = true)
    private String name;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "dog_id", nullable = false)
    private Dog dog;

    // getters, setters, constructors
}

So a dog can know several commands, and each command is unique for a dog (belongs only to one dog).

I have a view (website page) that allows the admin to add new commands to each dog and also change the dog's name.

Once done, the view would send a POST request to /api/dog/edit with JSON like this:

{
  "commands": ["some command name", "another command name"],
  "id": 1,
  "name": "Updated Dog Name"
}

Now, because the Dog entity doesn't contain a List<Command> field, the controller can't map all of the JSON to the Dog entity, so I created a DogDto:

DogDto.java:

public class DogDto  {
  private Long id;
  private String name;
  private List<CommandDto> commands;  
  

  // getters, setters, constructors
}

and CommandDto:

CommandDto.java:

public class CommandDto  {
  private Long id;
  private String name;
  private DogDto dog;

  // getters, setters, constructors
}

Now my controller can map the JSON passed from view to the DogDto:

@RestController
@RequestMapping(path = "api/dog")
public class DogController {
    ...

    @PostMapping("edit")
    @CrossOrigin
    public ResponseEntity<DogDto> editDog(@RequestBody DogDto dogDto)  {
      ...
      Dog dog = mapper.map(dogDto, Dog.class);
      List<Command> commands = new ArrayList<>();
      for (CommandDto commandDto: dogDto.getCommands())  {
        Command command = mapper.map(commandDto, Command.class);
        commands.add(command);
      }
      ...
    }
}

Now I can map the DogDto to a Dog and Command entities. But what would be the best way to persist them? Currently my DogService has a

public boolean editDog(Dog dog) {...}

method that accepts a dog, tries to find it by ID:

Dog foundDog = this.dogRepository.findById(dog.getId());

and if the dog was found, update its name field and do this.dogRepository.save(foundDog);.

However I also need to save the commands. The Dog entity doesn't contain the list of commands. So I either need to change the editDog method signature to boolean editDog(DogDto dog) or do it in the controller like this:

for (Command command: commands)  {
  command.setDog(dogFoundById);
  this.commandService.createCommand(command);
}

I'm lost as to what to do here.

And I've also been wondering what if I had a more complex structure, with more nested entities:

public class A  {
  ...
  @OneToMany
  private List<B> bs;
}
public class C  {
  ...
  @ManyToOne
  private B b;
}

would the best design decision be different?