design – When components of an event-driven program require specific responses to specific events, is event-driven still the correct approach?

I’m working on a multi-threaded program that interfaces with external USB/serial devices via user-space device drivers.

Early in the design stage, I made the decision to split the program into three components: A, B and C.

  • Component A would possess full responsibility of communication with external devices (this is where the user-space device drivers would run). It would run on a dedicated thread.
  • Component B would serve an API off of a TCP/IP socket to third-party clients that needed access to the external devices. This component would also run on a dedicated thread.
  • Component C would provide a GUI for the user, allowing them to view and manipulate data from the external devices. Again, this would be on a dedicated thread.

So components B and C both require access to the external devices, which component A would provide.

I needed a way for the three components to interface with each other, and at the time I thought making the program event-driven would be appropriate. With this approach, components would emit an event and other components would handle those events. I always knew that some events would require responses, in the form of subsequent events. For example, if component C wanted to pull some data from the external device, to present to the user in the GUI, it would emit an event to request the data from component A, and component A would handle that event, and return the requested data in a subsequent event, which component C would be waiting for.

Since defining the above approach, I’ve realised that, in some cases, a component may require a specific response to a specific event. So building off of the example above, if component C and component B requested different data from component A, component C should be able to wait for the correct response event (that is, the response to the event emitted by component C).

So I’m considering implementing the ability for a component to wait for an event that is a direct response to the previously emitted event. I would do this via event IDs, where each event would carry an ID, and an optional response ID. The response ID would be the ID of the event that the current event is in response to.

But I feel like I’m on the wrong path. Is this really an appropriate use of event-driven design? Is it OK for events to serve as requests for data, and subsequent events as responses? Would you do it differently? If so, how?

EDIT/UPDATE:

I’ve just come across this video by Mark Richards, which seems to describe my approach with event IDs and response IDs (which he calls “correlation IDs”). So maybe I’m not on the wrong path – he seems to think using events for request/response is fine. Would still appreciate your thoughts.

complexity theory – Finding the Big-O and Big-Omega bounds of a program

I am asked to select the bounding Big-O and Big-Omega functions of the following program:

void recursiveFunction(int n) {
    if (n < 2) {
        return;
    }

    recursiveFunction(n - 1);
    recursiveFunction(n - 2);
}

From my understanding, this is a Fibonacci sequence, and according to this article here, https://www.geeksforgeeks.org/time-complexity-recursive-fibonacci-program/, the tight upper bound is $1.6180^n$. Thus, I chose all the Big-O bounds >= exp(n) and all the Big-Omega bounds <= exp(n). Below are the choices:

O(1)
O(log n)
O(n)
O(n^2)
O(exp(n))

Om(1)
Om(log n)
Om(n)
Om(n^2)
Om(exp(n))

The answer choices I selected:

O(n^2)
O(exp(n))

Om(1)
Om(log n)
Om(n)
Om(n^2)
Om(exp(n))

However, it was alerted that a few of my answers were incorrect (not sure which of them). This seems strange, considering that this recursive function mimics the calls of a fibonacci sequence which has a Big-Theta exponential time complexity.

Free anti-spam program for windows 10

You can use the build-in Windows Defender, which – last time I checked – has fairly good reputation for finding threats without too many false positive hits.
To add exclusions on-the-fly is not an option, but can be added manually in settings.

I have used AVG Free for years (easy adding exclusions).
It is free, but you have to be ready to deny offers to buy the paid version now and then.

I have earlier used Avast free, but is not sure if it is still a free option (often the free edition is “hidden” with small letters somewhere) 🙂

compilers – What is the name of this type of program optimization?

On an imperative programming language, let us consider the following program:

for i in 0..N { // N is the length of the arrays A, B, C.
  A[i] = A[i] + B[i];
}
for i in 0..N {
  A[i] = A[i] + C[i];
}

This program just sums three arrays $A + B + C$ component-wisely and store it to $A$.

We can easily transform this program into the following equivalent one:

for i in 0..N {
  let tmp = A[i] + B[i];
  A[i] = tmp + C[i];
}

I think the latter code is more efficient than the former because we can decrease the number of memory accesses.

Now I have a question.

What is the name of this type of program transform or program optimization?
Can we also call this deforestation?

python 3.x – Image shows normally on simple program, but appears blank when I introduce it to mine (Tkinter)

I am trying to show a graph on the screen that I just plotted using matplotlib on python.
Basically, my program receives a bunch of parameters and then makes a graph, that should be displayed on screen.
Since I am new to tkinter, I made a simple program to see if the code worked:

from tkinter import *
from PIL import ImageTk, Image
root=Tk()

my_img1=ImageTk.PhotoImage(Image.open("plot.png"))   
my_label=Label(image=my_img1)
my_label.grid(row=0,column=0,columnspan=3)

mainloop()  

This works just fine.

However, when I introduce it into my actual program:

def graficar_fracciones():
    
    lista_de_ERRtotal=()
    for i in range(1,50):
        agregar=ERR_total(i)
        if agregar <0:
            lista_de_ERRtotal.append(0)
        else:
            lista_de_ERRtotal.append(agregar)
    plt.figure(figsize=(1.5,1))
    plt.plot(lista_de_ERRtotal)
    plt.xlabel("Cantidad de fracciones")
    plt.ylabel('ERR Total')
    plt.savefig('plot.png', dpi=300, bbox_inches='tight')
    my_img1=ImageTk.PhotoImage(Image.open("plot.png"))   
    my_label=Label(image=my_img1)
    my_label.grid(row=0,column=0,columnspan=3) 
    return

This function graphs the plot, then saves it. Then I open that plot and try to show it on screen, but it just shows blank.
Why could this be happening? I have checked some similar posts, but haven’t been able to find an answer.

linux – How to take image backups of the partition the backup program is running on

I am trying to take image backups for my system. I am running on a VPS from a hosting website. I wanted to try to make backups using an image software like clonezilla but that didn’t work as I wasn’t able to upload custom ISOs. I wanted a image backup as then it would save the entire filesystem and I wouldn’t have to worry about issues like deja dup not being able to overwrite files when restoring them. Here is what I tried.

I tried to use partclone to clone the image but then realized partclone won’t work if it is running on the partition you want to backup. I tried to convert my ext4 partition (which is my main partition running my linux system) to lvm. Apparently partclone doesn’t have an issue when running on lvm to backup the partition its running on (Im not sure if that is true but I read that while trying to solve this issue). I wasn’t able to convert the system to lvm as it seems extremely complex.

Is there any way I could create a image backup of a system running on a VPS or will I have to use some sort of backup software like timeshift or deja dup. I just need backups. That is the goal.

linux – Is there a program to scan and correct names of many files and avoid errors and failure during copying?

It seems that the problem reported in this question about Mac and Windows not being able to access some files and folders created in Linux is due to bad characters hidden somehow in their names (see also the commentaries thereunder). I personally think that such errors happened during copying, but that the bad results affect less Linux than the rest of the operating systems. See the end of my answer under linked question about a second event.

Trying to do the copying on a Mac the process was again stopped with an error saying something like some file couldn’t be read or written. I guess it’s the same type of error.

I have to start all over again and I guess I should do it in Linux, where I have many tools at my disposal and can most easily identify an error when it happens.

I guess a good solution for me would be a program (preferably on Linux or Windows) that would be able to identify and fix those names (and eliminate those ‘phantom’ characters).

PlayCash Network – gambling and betting affiliate program with top conditions! | NewProxyLists

Who are we?
We are a team of professionals in adtech and affiliate marketing who have been with you for over 10 years (such projects as Dao.ad, TerraLeads and others), and now we are presenting PlayCash Network – affiliate network for making profit on gambling traffic.

What we offering​

Our verticals are gambling, betting and binary options.
Now we have more than 150 tested offers by CPA, CPL and Revenue Share models from all over the world:

  • The CIS (CPA up to $65)
  • Europe (CPA up to $250, CPL up to $20)
  • Latin America (CPA up to $100)
  • Middle East (CPA up to $150)
  • Oceania (CPA up to $170)
  • island territories (CPA up to $150, CPL up to $15)
  • and many others.

Why it worth to work with us​

  • We have pre-landing pages for gambling offers that are free for our partners
  • We make payments every week to such payment systems as Webmoney, Payoneer, Capitalist, Wire, etc.
  • For affiliate teams and affiliate experts with big turnovers (20+ deposits per day), we are ready to provide payments on request and to payment systems convenient for you, advance payment of your tests and other financial conditions negotiablel.
  • Don’t found offer you were looking for? Contact our manager, and we will find it for you. We are in touch with almost all advertisers in the industry, and if something is missing, it’s just a temporary misunderstanding.

What traffic we accept​

We accept traffic from any sources allowed by local advertising laws. Of course, there are more offers for popular directions like Facebook, push notifications, clickunders, native advertising, etc., but if you work with more exotic methods of attracting players, we will definitely direct you to a profitable channel.

How to contact us​

If you have questions about cooperation, contact our manager:
Roman
@roman_playcash (telegram)
live: roman.kusher (skype)
roman@playcash.network

 

c# – Caculater Program improvments

I’m pretty new to programming and made a few programs so far. I recently made a Caculater program and I hope you guys could tell me what I could do to improve.

int firstNumber;
        string sign;
        int secondNumber;
        int answer;


        Console.WriteLine("Input Number:");
        firstNumber = Convert.ToInt32(Console.ReadLine());
        Console.Clear();

        Console.WriteLine("Input Sign:");
        sign = Console.ReadLine();
        Console.Clear();

        Console.WriteLine("Input Second Number:");
        secondNumber = Convert.ToInt32(Console.ReadLine());
        Console.Clear();

        switch (sign)
        {
            case "+":
                answer = firstNumber + secondNumber;
                Console.WriteLine(answer);
                Console.ReadKey();
            break;
            case "-":
                answer = firstNumber - secondNumber;
                Console.WriteLine(answer);
                Console.ReadKey();
            break;
            case "*":
                answer = firstNumber * secondNumber;
                Console.WriteLine(answer);
                Console.ReadKey();
            break;
            case "/":
                answer = firstNumber / secondNumber;
                Console.WriteLine(answer);
                Console.ReadKey();
            break;
            default:
                Console.WriteLine("Invalid Input");
            break;
        }

java – Program that helps you search for torrents

I wrote a desktop application in java (with JavaFX). Program first find given title in Imdb via: https://imdb-internet-movie-database-unofficial.p.rapidapi.com and then when user select a movie, search in the pirate bay site for magnets link, seeds and leechers. Here is an example:

enter image description here

Here are two classes:

ImdbFinder

package service.movie;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.JsonArray;
import exception.NoMovieFoundException;
import model.Movie;
import service.util.JsonParserUtil;
import service.util.PropertyHelper;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Properties;

public class ImdbFinder implements MovieFinder {

    private static ImdbFinder instance;
    private static Properties properties;
    private static ObjectMapper objectMapper;

    private ImdbFinder() { }

    public static ImdbFinder getInstance() {
        if (instance == null) {
            instance = new ImdbFinder();
            objectMapper = new ObjectMapper();
            properties = PropertyHelper.loadPropertyFileForFilename("ImdbHttpInfo.properties");
        }
        return instance;
    }

    @Override
    public Movie getMovieDetailsForMovieId(String movieId) {
        return new Movie();
    }

    @Override
    public List<Movie> getMovieListForSearchedPhrase(String phrase) throws IOException, InterruptedException, NoMovieFoundException {
        List<Movie> movies = mapTitlesToMovieList(foundMovies(phrase).body());
        if (movies == null || movies.isEmpty()) {
            throw new NoMovieFoundException();
        }
        return movies;
    }

    private List<Movie> mapTitlesToMovieList(String response) throws IOException {
        Optional<JsonArray> jsonArray = Optional.ofNullable(
                JsonParserUtil.parseStringToJsonObject(response).getAsJsonArray("titles"));

        List<Movie> movieList = new ArrayList<>();
        if (jsonArray.isPresent()) {
            movieList = objectMapper.readValue(jsonArray.get().toString(), new TypeReference<List<Movie>>() {});
        }

        return movieList;
    }

    private HttpResponse<String> foundMovies(String title) throws IOException, InterruptedException {
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(properties.getProperty("search-api-url") + formatTitle(title)))
                .header("x-rapidapi-key", properties.getProperty("x-rapidapi-key"))
                .header("x-rapidapi-host", properties.getProperty("x-rapidapi-host"))
                .method("GET", HttpRequest.BodyPublishers.noBody())
                .build();
        System.out.println(URI.create(properties.getProperty("search-api-url") + formatTitle(title)));
        return HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
    }

    private String formatTitle(String title) {
        return title.replaceAll("\s+", "%20")
                .replaceAll("(^a-zA-Z\d\s%)", "");
    }
}

PirateBayFinder

package service.torrent;

import exception.NoTorrentFoundException;
import model.Torrent;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PirateBayFinder implements TorrentFinder {

    private static TorrentFinder instance;

    private static final String SEARCH_URL = "https://tpb.party/search/";

    private static final String MAGNET_REGEX = "magnet:\?xt=(.*?)(?=")";
    private static final String TITLE_INSIDE_MAGNET_REGEX = "(?<=&dn=)(.*?)(?=&tr)";
    private static final String SEEDS_LECHERS_PATTERN = "(?<=<td align="right">)((0-9)*?)(?=</td>)";

    private PirateBayFinder() { }

    public static TorrentFinder getInstance() {
        if (instance == null) {
            instance = new PirateBayFinder();
        }
        return instance;
    }

    @Override
    public List<Torrent> findTorrentsForPhrase(String phrase) throws IOException, InterruptedException, NoTorrentFoundException {

        String htmlPage = foundTorrents(phrase).body();

        List<Torrent> foundTorrents = new ArrayList<>();

        scrapTorrentInfo(htmlPage, foundTorrents);
        scrapSeedsAndLeechers(htmlPage, foundTorrents);

        if (foundTorrents.isEmpty()) {
            throw new NoTorrentFoundException();
        }

        return foundTorrents;
    }

    private void scrapTorrentInfo(String htmlPage, List<Torrent> foundTorrents) {
        Matcher magnetMatcher = Pattern.compile(MAGNET_REGEX).matcher(htmlPage);
        Pattern titlePattern = Pattern.compile(TITLE_INSIDE_MAGNET_REGEX);
        Matcher titleMatcher;
        String title;
        String magnet;
        while (magnetMatcher.find()) {
            magnet = magnetMatcher.group();
            titleMatcher = titlePattern.matcher(magnet);
            if (titleMatcher.find()) {
                title = titleMatcher.group();
                foundTorrents.add(new Torrent(title, magnet));
            }
        }
    }

    private void scrapSeedsAndLeechers(String htmlPage, List<Torrent> foundTorrents) {
        final Matcher seedsLeechersMatcher = Pattern.compile(SEEDS_LECHERS_PATTERN).matcher(htmlPage);
        int seeds, lecheers;
        int counter = 0;
        while(seedsLeechersMatcher.find()) {
            seeds = Integer.parseInt(seedsLeechersMatcher.group());
            lecheers = 0;
            if (seedsLeechersMatcher.find()) {
                lecheers = Integer.parseInt(seedsLeechersMatcher.group());
            }
            foundTorrents.get(counter).setSeeds(seeds);
            foundTorrents.get(counter).setLeechers(lecheers);
            counter++;
        }
    }

    private HttpResponse<String> foundTorrents(String title) throws IOException, InterruptedException {
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(SEARCH_URL + title.replaceAll("\s+","%20")))
                .method("GET", HttpRequest.BodyPublishers.noBody())
                .build();
        System.out.println(request.uri());
        return HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
    }
}

and two interfaces:

MovieFinder

public interface MovieFinder {

    Movie getMovieDetailsForMovieId(String id);

    List<Movie> getMovieListForSearchedPhrase(String phrase) throws IOException, InterruptedException;

}

TorrentFinder

public interface TorrentFinder {

    List<Torrent> findTorrentsForPhrase(String phrase) throws IOException, InterruptedException;

}

Could you please tell me what can I improve int these two classes? I think code which contains matchers and patterns looks too complicated.