โŒ

Normal view

There are new articles available, click to refresh the page.
Yesterday โ€” 28 April 2024Main stream

Tree traversal function works correctly inside loop but not outside

I am trying to solve the exercises 6.3 from the K & R C programming book. The text is: Write a cross-referencer that prints a list of all words in a document, and for each word, a list of the line numbers on which it occurs. Remove noise words like the,'' and,'' and so on. Here is my solution:


struct lnode {
    int linen;
    lnode *next;
};

struct tnode {
    char *value;
    tnode *left;
    tnode *right;
    lnode *lines;
};

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MAXWORD 8192

int getword (char *word, int size, int *line);
void displaytree (struct tnode *node);
struct tnode* addtree (struct tnode *node, char *word, int line);
void deletetree (struct tnode *node);
void displaylines (struct lnode *node);

char noisewords [][MAXWORD] = {"the", "and"};


int main (int argc, char *argv[]) {
    struct tnode *root;
    // initialize FIRST root to null
    root = NULL;

    int line = 0;
    char word[MAXWORD];

    while (getword(word, MAXWORD, &line) != EOF) {
        root = addtree(root, word, line);
    }

    displaytree(root);
    deletetree(root);
}


void displaytree (struct tnode *node) {
    if (node != NULL) {
        displaytree (node -> left);
        printf("(%s)", node -> value);
        displaylines (node -> lines);
        displaytree (node -> right);
    }
    
}

void displaylines (struct lnode *node) {
    if (node != NULL) {
        printf("%d", node -> linen);
        displaylines(node -> next);
    } 
}

/* for malloc and free */
#include <stdlib.h>

void deletelist(struct lnode *listnode) {
  if(listnode != NULL) {
    deletelist(listnode->next);
    free(listnode);
  }
}

void deletetree (struct tnode *node) {

    struct tnode *temp = NULL;

    if (node != NULL) {
        if (node -> right != NULL) {
            temp = node;
            deletetree(temp -> right);
        }
        if (node -> left != NULL) {
            temp = node;
            deletetree(temp -> left);
      }
      if (node -> value != NULL) {
        free(node -> value);
      }
      
      if (node -> lines != NULL) {
        deletelist(node -> lines);
      }

      free(node);
      node = NULL;
    }
}

struct tnode* talloc (void);
char* strdup (char *word);
struct lnode* addline (int line);

struct tnode* addtree (struct tnode *node, char *word, int line) {
    if (node == NULL) {
        node = talloc();
        if (node != NULL) {
            node -> value = strdup(word);
            node -> left = NULL;
            node -> right = NULL;
            node -> lines = addline(line);
        }
    }
    else {
        if (strcmp(word, node -> value) == 0) {
            /* should not happen, if node != NULL then also node -> lines is different from NULL. */
            if (node -> lines == NULL) {
                node -> lines = addline(line);
            }
            else {
                struct lnode *current = node -> lines;
                while (current -> next != NULL) {
                    current = current -> next;
                }
                current -> next = addline(line);
            }
        }
        else if (strcmp(word, node -> value) < 0) {
            node -> left = addtree (node -> left, word, line);
        }
        else {
            node -> right = addtree (node -> right, word, line);
        }
    }    
    return node;
}

struct lnode* lalloc (void);

struct lnode* addline (int line) {
    struct lnode *node = lalloc();
    if (node != NULL) {
        node -> linen = line;
        node -> next = NULL;
    }
    return node;
}

struct tnode* talloc (void) {
    return (struct tnode*) malloc(sizeof(struct tnode));
}

struct lnode* lalloc (void) {
    return (struct lnode*) malloc(sizeof(struct lnode));
}

char* strdup (char *word) {
    char *p;
    p = (char *)malloc(strlen(word) + 1);
    if (p != NULL)
        strcpy(p, word);
    return p;
}

int getch (void);
void ungetch (int c);

int getword (char *word, int size, int *line) {
    int c, getch(void);
    void ungetch(int);
    char *w = word;

    while (isspace(c = getch()))
        ;

    if (c != EOF)
        *w++ = c;
    
    if (!isalpha(c)) {
        *w = '\0';
        return c;
    }

    for ( ; --size > 0; w++)
        if (!isalnum(*w = getch())) {
            /* count the number line */
            if (*w == '\n')
                *line += 1;
            ungetch(*w);
            break;
        }
    *w = '\0';
    return word[0];
}

#define BUFSIZE 1000
char buf[BUFSIZE];
int bufc = 0;

int getch (void) {
    return (bufc > 0) ? buf[--bufc] : getchar();
}

void ungetch (int c) {
    if (bufc >= BUFSIZE) {
        printf("The buffer is full!\n");
        return;
    }
    buf[bufc++] = c; 
}

However, if i give as input something like:

the pen is on the table the cat is under the cat

The output provided is:

(cat)(is)(on)(pen)

By executing the displaytree inside the while loop:


int main (int argc, char *argv[]) {
    struct tnode *root;
    // initialize FIRST root to null
    root = NULL;

    int line = 0;
    char word[MAXWORD];

    while (getword(word, MAXWORD, &line) != EOF) {
        root = addtree(root, word, line);
        printf("[");
        displaytree(root);
        printf("]\n");
    }
    deletetree(root);
}

I obtain as output:

[(the)]
[(pen)(the)]
[(is)(pen)(the)]
[(is)(on)(pen)(the)]
[(is)(on)(pen)(the)]
[(is)(on)(pen)(table)(the)]
[(is)(on)(pen)(table)(the)]
[(cat)(is)(on)(pen)(table)(the)]
[(cat)(is)(on)(pen)(table)(the)]
[(cat)(is)(on)(pen)(table)(the)(under)]
[(cat)(is)(on)(pen)(table)(the)(under)]
[(cat)(is)(on)(pen)(table)(the)(under)]

Which, not considering how the tree is displayed gives all the nodes of the tree: [(cat)(is)(on)(pen)(table)(the)(under)]

Can anyone explain me why outside the while, the tree is not correcly displayed/built?

[NSJSONSerialization dataWithJSONObject:options:error:]: Invalid top-level type in JSON write

When I run the code, I get the error ---------------------- "[NSJSONSerialization dataWithJSONObject:options:error:]: Invalid top-level type in JSON write". ----------------------

class BaseAPI<T: TargetType> {
    
    func fetchData<M: Decodable>(target: T, responseClass: M.Type, completion:@escaping(Result<M?, NSError>) -> Void) {
        let method = Alamofire.HTTPMethod(rawValue: target.methods.rawValue)
        let headers = Alamofire.HTTPHeaders(target.headers ?? [:])
        let params = buildParams(task: target.task)
        AF.request(target.baseUrl + target.path, method: method, parameters: params.0, encoding: params.1, headers: headers).responseDecodable(of: M.self) { response in
            guard let statusCode = response.response?.statusCode else {
                //ADD Custom Error
                completion(.failure(NSError()))
                return
            }
            if statusCode == 200 {
                // Successful Request
                guard let jsonResponse = try? response.result.get() else {
                    completion(.failure(NSError()))
                    return
                }
                guard let theJSONData = try? JSONSerialization.data(withJSONObject: jsonResponse, options: []) else {
                    completion(.failure(NSError()))
                    return
                }
                guard let responseObj = try? JSONDecoder().decode(M.self, from: theJSONData) else {
                    completion(.failure(NSError()))
                    return
                }
                completion(.success(responseObj))
                
            } else {
                completion(.failure(NSError()))
            }
        }
        
        
    }
    
    private func buildParams(task: Task) -> ([String:Any], ParameterEncoding) {
        switch task {
            
        case .requestPlain:
            return ([:], URLEncoding.default)
        case .requestParameters(parameters: let parameters, encoding: let encoding):
            return (parameters, encoding)
        }
    }
}

instead of try? JSONSerialization.data(withJSONObject: jsonResponse, options: []) When I try the try? JSONSerialization.data(withJSONObject: jsonResponse, options: []) code, it gives the error No exact matches in call to class method 'jsonObject'.

Why does my angular app hosted on nginx throw me an error 502 bad gateway error, but build in the terminal

Yo I've been trying to host an Angular app on NGINX with Docker but when I build the container and go to localhost:8080 I get an 502 Bad Gateway error.

This is my Dockerfile:

FROM node:latest as build

WORKDIR /usr/local/app

COPY package.json .

RUN npm install

COPY . .

CMD ["npm", "start"]

This is my docker-compose.yml:

version: "3.9"

services:
  app:
    container_name: app
    build:
      context: .

  nginx:
    container_name: nginx
    image: nginx
    ports:
      - "80:80"
    depends_on:
      - app
    volumes:
      - ./default.conf:/etc/nginx/conf.d/default.conf

This is my default.conf file:

server {
    listen 80;
    server_name app;
    location / {
        proxy_pass http://app:4200;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

This is the line I'm using to build the image:

docker build -t front .

This is the line I'm using to run the image:

docker run -d -p 8080:80 front

And also use:

docker compose up -d

And i have this error

2024/04/28 14:47:13 [error] 32#32: *7 connect() failed (111: Connection refused) while connecting to upstream, client: 172.18.0.1, server: app, request: "GET /favicon.ico HTTP/1.1", upstream: "172.18.0.2:4200/favicon.ico", host: "localhost", referrer: "localhost" this is the error I need help with this error

Dependency alias 'androidx-material3-adaptive-navigation-suite' is not used in build scripts

I'm trying to implement the Navigation Suite library provided by Material Design 3 for my Jetpack Compose Project but after several gradle syncs, a warning won't go away.

build.gradle.kts (:app)

plugins {
    alias(libs.plugins.androidApplication)
    alias(libs.plugins.jetbrainsKotlinAndroid)
}

android {
    namespace = "com.plaireapps.demonavigationsuite"
    compileSdk = 34

    defaultConfig {
        applicationId = "com.plaireapps.demonavigationsuite"
        minSdk = 30
        targetSdk = 34
        versionCode = 1
        versionName = "1.0"

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
        vectorDrawables {
            useSupportLibrary = true
        }
    }

    buildTypes {
        release {
            isMinifyEnabled = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = "1.8"
    }
    buildFeatures {
        compose = true
    }
    composeOptions {
        kotlinCompilerExtensionVersion = "1.5.1"
    }
    packaging {
        resources {
            excludes += "/META-INF/{AL2.0,LGPL2.1}"
        }
    }
}

dependencies {

    implementation(libs.androidx.core.ktx)
    implementation(libs.androidx.lifecycle.runtime.ktx)
    implementation(libs.androidx.activity.compose)
    implementation(platform(libs.androidx.compose.bom))
    implementation(libs.androidx.ui)
    implementation(libs.androidx.ui.graphics)
    implementation(libs.androidx.ui.tooling.preview)
    implementation(libs.androidx.material3)
    testImplementation(libs.junit)
    androidTestImplementation(libs.androidx.junit)
    androidTestImplementation(libs.androidx.espresso.core)
    androidTestImplementation(platform(libs.androidx.compose.bom))
    androidTestImplementation(libs.androidx.ui.test.junit4)
    debugImplementation(libs.androidx.ui.tooling)
    debugImplementation(libs.androidx.ui.test.manifest)
}

libs.versions.toml

[versions]
agp = "8.3.2"
kotlin = "1.9.0"
coreKtx = "1.13.0"
junit = "4.13.2"
junitVersion = "1.1.5"
espressoCore = "3.5.1"
lifecycleRuntimeKtx = "2.7.0"
activityCompose = "1.9.0"
composeBom = "2024.04.01"

[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-ui = { group = "androidx.compose.ui", name = "ui" }
androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
androidx-material3-adaptive-navigation-suite = { module = "androidx.compose.material3:material3-adaptive-navigation-suite-android", version = "1.0.0-alpha06" }

[plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" }
jetbrainsKotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }

Warning returned

Dependency alias 'androidx-material3-adaptive-navigation-suite' is not used in build scripts

How to call a Perl script with couple of arguments with html tag from within a Python script using Subprocess/shell? HTML tagging not working

Within a python script I have a function which looks as below:

def NotifierFunc(Mail, Ticket_Num, Open_DtTime):
    cmd = "/home/path/MyPerlScript.pl --channel 'MyChannel' --userid 'itsme' --message 'Hello \<at\>"+Mail+"\<at\> : The ticket \<a href='`echo 'http://snview/'"+Ticket_Num+">`echo "+Ticket_Num+"\`\</a\> is not closed for more than 72 hours : Open since "+Open_DtTime+" IST. Please close asap.' "
    print(cmd)
    subprocess.Popen(cmd, shell= True, stout=subprocess.PIPE)

This command does not get executed successfully in the shell primarily because the the message (all that is passed after '--message' is put within single quotes). When I put that under double quotes python script throws syntax error. When I put the whole cmd value in either single quote or doc string quote and message content in double quote that results in syntax error as well. When I run the cmd directly on linux shell with the message content placed within double quotes it works absolutely fine.

Now my question is how can I pass on this whole cmd value to subprocess so that the content of '--message' can be rendered correctly - or how can put the '--message' content within double quotes and make it work. Please note if I pass on the cmd as below - it works fine but it does not have the hyperlink for the ticket number. But I need the hyperlink.

cmd = "/home/path/MyPerlScript.pl --channel 'MyChannel' --userid 'itsme' --message 'Hello \<at\>"+Mail+"\<at\> : The ticket \+Ticket_Num+" is not closed for more than 72 hours : Open since "+Open_DtTime+" IST. Please close asap.' "

I have also tried putting the variables within {} and have tried various quote combinations. Nothing works so far. I am using python 3.10

ReferenceError when I put fullRepresentation

I'm trying to create a Plasmoid (Plasma 6) I need fullRepresentation and compactRepresentation to display dynamically generated switches, for now I'm working on fullRepresentation

if I put this :

  fullRepresentation: ColumnLayout {
    id: fullRoot
    Repeater {

I have this error :

qml: Toggling action for: isMain_666 to true
qml: Executing command: isMain_666|sleep 2; exit 1
qml: New data from switch: isMain_666 for command: sleep 2; exit 1 with data: [object Object]
file:///home/xkain/.local/share/plasma/plasmoids/com.xkain.Ultimat-ToggleSwitch/contents/ui/main.qml:32: ReferenceError: switchRepeater is not defined

But if I remove "fullRepresentation:" everything works perfectly:

  ColumnLayout {
         id:fullRoot
         Repeater {

here is the complete code:

import QtQuick
import QtQuick.Layouts
import QtQuick.Controls

import org.kde.plasma.plasmoid
import org.kde.plasma.core as PlasmaCore
import org.kde.plasma.plasma5support as Plasma5Support
import org.kde.plasma.components as PlasmaComponents3
import org.kde.kirigami as Kirigami

PlasmoidItem {
    id: root

    readonly property var switches: JSON.parse(Plasmoid.configuration.switches)
    Plasmoid.backgroundHints: PlasmaCore.Types.DefaultBackground | PlasmaCore.Types.ConfigurableBackground

    preferredRepresentation: fullRepresentation


    Plasma5Support.DataSource {
        id: executable
        engine: "executable"
        connectedSources: []

        onNewData: function(sourceName, data) {
            var parts = sourceName.split('|');  // Split the source name to retrieve switchId and the command
            var switchId = parts[0];
            console.log("New data from switch:", switchId, "for command:", parts[1], "with data:", data);

            for (var i = 0; i < root.switches.length; ++i) {
                if (switches[i].switchId === switchId) {
                    var switchDelegate = switchRepeater.itemAt(i);
                    if (!switchDelegate) {
                        console.error("Switch delegate not found for switchId:", switchId);
                        continue;
                    }
                    if (data['exit code'] != 0) {
                        switchDelegate.checked = !switchDelegate.checked;
                    }

                    disconnectSource(sourceName);
                    break;
                }
            }
        }


        function exec(switchId, cmd) {
            var commandWithId = switchId + "|" + cmd;
            console.log("Executing command:", commandWithId);
            connectSource(commandWithId);
        }
    }

    function toggleAction(switchId, checked) {
        console.log("Toggling action for:", switchId, "to", checked);
        for (var i = 0; i < switches.length; ++i) {
            if (switches[i].switchId === switchId) {
                switches[i].checked = checked;
                var script = checked ? switches[i].onScript : switches[i].offScript;
                executable.exec(switchId, script);

                if (switches[i].isMaster) {
                    // Toggle all isMain below this master until next master or end of list
                    toggleDependentSwitches(i, checked);
                }
                break;
            }
        }
    }

    function toggleDependentSwitches(masterIndex, checked) {
        console.log("Toggling dependent switches for master index:", masterIndex, "to", checked);
        for (var i = masterIndex + 1; i < switches.length; i++) {
            if (switches[i].isMaster) break; // Stop if another master is found
            if (switches[i].positionByMaster) {
                switches[i].checked = checked;
                var delegate = switchRepeater.itemAt(i);
                if (delegate) {
                    delegate.checked = checked;
                    var script = checked ? switches[i].onScript : switches[i].offScript;
                    executable.exec(switches[i].switchId, script);
                }
            }
        }
    }

    fullRepresentation: ColumnLayout {
        id: fullRoot
        Repeater {
            id: switchRepeater
            model: root.switches
            delegate: PlasmaComponents3.Switch {
                id: switchItem
                text: modelData.name
                Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
                checked: modelData.defaultPosition
                onCheckedChanged: {
                    root.toggleAction(modelData.switchId, switchItem.checked);
                }
            }
        }
    }

    compactRepresentation: {}
}

How can I fix this error? I'm just starting to learn programming so I certainly made a mistake somewhere but I'm stuck.

Why is unittest returning ValueError (not in list) when the element is in the list?

I have a function which searches a Bank for a specific Account object. If it finds a matching account, the function replaces the Account object with None. If it finds no match, it returns. This works perfectly in IDLE.

My unittest for this function keeps returning ValueError: <Mock id='2350965017280'> is not in list.

Here is the function:

def removeAccountFromBank(self, account):
        target_index = accounts.index(account)
        accounts[target_index] = None
        return

Here is my test (using unittest):

def test_removeAccountFromBank(self):
        account = Mock()
        bank = Bank()
        accounts = [None, (account), None]
        print(accounts)
        bank.removeAccountFromBank(account)
        self.assertEqual(bank.get_accounts(), [None, None, None])

I expected this test to pass, but here is the result I got:

The print statement correctly shows the account: [None, <Mock id='2350965017280'>, None]

But I get an error when the function tries to find the account using index:

in removeAccountFromBank target_index = accounts.index(account) ValueError: <Mock id='2350965017280'> is not in list

I am confused about why the accounts.index part is returning a ValueError. I also tried printing the accounts.index(account) and it returns the correct index of 1.

python function set value according to master dataframe

I need to define a function that, depending on the value of the input variable and a master dataframe, the function assigns the return value according to a master dataframe.

This is the master (df_master) dataframe the function has to recieve and, depending on it and the input value, return value:

value (from) value (until) value to return
0 30 1
31 50 2
51 100 3

For example, if input value = 10, return 1

For example, if input value = 90, return 3

...

The function should be something like:

def assing_value (input_var, df_master):
    ...

Thanks.

def assign(input_variable, df_master):
    ...

Maximum number of elements on list whose value sum up to at most K in O(log n)

I have this exercise to do:

Let M be a positive integer, and V = โŸจv1, . . . , vnโŸฉ an ordered vector where the value of item vi is 5ร—i.

Present an O(log(n)) algorithm that returns the maximum number of items from V that can be selected given that the sum of the selected items is less than or equal to M (repeated selection of items is not allowed).

First I did a naive solution where:

  • I know the sum of elements on the array will be always less than the M/5 index on the array. So a did for i=0..i<=M/5 and found the sum. Moreover this is not O(log(n)) because given a big M, bigger than the sum of all elements on the array, it will be O(n).

Therefore I tried divide and conquer, I thought a binary search should be the way. But actually no because if I do that I will sum the minimum elements that can be chosen to arrive in M, not the maximum. My code is below

   def max_items_selected_recursive2(M, V, left, right, max):

    if len(V[left:right]) == 1:
      return max
    

    mid =  math.floor((left+right)/2)
    if  V[mid] >= M:
        return max_items_selected_recursive2(M - V[mid], V, mid + 1, right, max+1)
    else:
        if  M - V[mid] >= 0:
          return max_items_selected_recursive2(M - V[mid], V, left, mid - 1, max+1)
        else: 
          return max_items_selected_recursive2(M, V, left, mid - 1, max)
   

example of call

M = 20
  V = [0, 5, 10, 15, 20]
  max_items_selected_recursive2(M, V, 0, len(V) - 1, 0) +1 # +1 since all have the O element

Any ideas on how to do this on O(log n)?

Java reworked 'FTP' File Transfer with Ascii and Binary

I'm having to implement a basic file transfer system in Java, one that accepts commands from the client. Unfortunately, the class this was for has so far been more about networking concepts as opposed to code, so I am struggling a bit with the proper way to go about it. For any kind enough to help, if there's a good guide or documentation somewhere as to how to do this I would be eternally grateful.

The current issue I am running into right now is that sometimes after I download or upload a file, it won't let me put any more input and the client is essentially frozen. I believe it to be the server and client getting out of sync, but I have no clue where.

I'm aware that this code is an absolute mess so if there's a guide already written or an example somewhere on how to properly do it you can just point me there instead of having to strain your eyes understanding all this spaghetti.

Client Side:

import java.io.*;
import java.net.*;

public class FTPClient {
   
    public static void main(String[] args) {
        String serverAddress = "localhost"; 
        int portNumber = 8888; 
        

        try (
            Socket socket = new Socket(serverAddress, portNumber);
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
            BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in))
        ) {
            // Handle server's initial welcome message or prompt
            System.out.println(in.readLine());  // Read and display the "Please enter your username:" message

            // Send username and handle response
            String username = stdIn.readLine();
            out.println(username);
            System.out.println(in.readLine());  // Read and display the "Please enter your password:" message

            // Send password and check for authentication
            String password = stdIn.readLine();
            out.println(password);

            String serverResponse = in.readLine();
            if (!serverResponse.startsWith("230")) {
                System.out.println("Authentication failed: " + serverResponse);
                return;
            }

            System.out.println("Authentication successful. Enter commands:");

            // Handle commands
            String userInput;
            while ((userInput = stdIn.readLine()) != null) {
                if (userInput.equalsIgnoreCase("QUIT")) {
                    out.println("QUIT");
                    System.out.println("Quitting...");
                    break;
                } else if (userInput.equalsIgnoreCase("LIST")) {
                    out.println("LIST");
                    String response;
                    while (!(response = in.readLine()).equals("226 Directory listing complete")) {
                        System.out.println(response);
                    }
                } else if (userInput.startsWith("DOWNLOAD ")) {
                    String fileName = userInput.substring(9); // Extracting filename from the command
                    receiveFile(fileName, socket);
                } else if (userInput.startsWith("UPLOAD ")) {
                    String fileName = userInput.substring(7); // Extracting filename from the command
                    sendFile(fileName, socket, in);
                } else {
                    System.out.println("Server response: " + in.readLine());
                }
            }
        } catch (UnknownHostException e) {
            System.err.println("Unknown host: " + serverAddress);
        } catch (IOException e) {
            System.err.println("Error connecting to server: " + e.getMessage());
        }
    }

    private static void sendFile(String fileName, Socket socket, BufferedReader in) {
        try {
            File file = new File(fileName);
            if (file.exists()) {
                PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
                out.println("UPLOAD " + fileName);
                FileInputStream fis = new FileInputStream(file);
                BufferedInputStream bis = new BufferedInputStream(fis);

                byte[] buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = bis.read(buffer)) != -1) {
                    socket.getOutputStream().write(buffer, 0, bytesRead);
                }
                bis.close();    
                fis.close();


                out.println("226 Transfer complete.");
                System.out.println("File uploaded successfully");
               
                
            } else {
                System.out.println("File not found.");
            }
        } catch (IOException e) {
            System.err.println("Error sending file: " + e.getMessage());
        }
    }

    private static void receiveFile(String fileName, Socket socket) {
        try {
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
            out.println("DOWNLOAD " + fileName);
            FileOutputStream fos = new FileOutputStream(fileName);
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = socket.getInputStream().read(buffer)) != -1) {
                bos.write(buffer, 0, bytesRead);
                if (bytesRead < 4096) {
                    break;
                }
                
            }
            bos.close();
            fos.close();
            
            
            
            System.out.println("File downloaded successfully");
        } catch (IOException e) {
            System.err.println("Error receiving file: " + e.getMessage());
        }
    }
}

And this is the server side:

import java.io.*;
import java.net.*;
import java.nio.file.*;

public class FTPServer {
    private static final String ROOT_DIRECTORY = "C:\\Users\\pokem\\Documents\\CSCI 361\\Server Side"; // Directory where files are stored

    public static void main(String[] args) {
        int portNumber = 8888; 

        try (ServerSocket serverSocket = new ServerSocket(portNumber)) {
            System.out.println("Server started. Waiting for clients...");

            while (true) {
                Socket clientSocket = serverSocket.accept();
                System.out.println("Client connected: " + clientSocket);

                // Handle each client in a separate thread
                new ClientHandler(clientSocket).start();
            }
        } catch (IOException e) {
            System.err.println("Error in server: " + e.getMessage());
        }
    }

    static class ClientHandler extends Thread {
        private Socket clientSocket;
        private PrintWriter out;
        private BufferedReader in;
        private boolean authenticated = false;

        public ClientHandler(Socket socket) {
            this.clientSocket = socket;
            try {
                out = new PrintWriter(clientSocket.getOutputStream(), true);
                in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void run() {
            try {
                // Authentication
                authenticate();
                if (!authenticated) {
                    clientSocket.close();
                    return;
                }

                // Main loop for handling client commands
                String inputLine;
                while ((inputLine = in.readLine()) != null) {
                    if (inputLine.equalsIgnoreCase("QUIT")) {
                        System.out.println("Client disconnected: " + clientSocket);
                        break;
                    } else if (inputLine.equalsIgnoreCase("LIST")) {
                        listFiles();
                    } else if (inputLine.startsWith("DOWNLOAD ")) {
                        String fileName = inputLine.substring(9); // Extracting filename from the command
                        sendFile(fileName);
                    } else if (inputLine.startsWith("UPLOAD ")) {
                        String fileName = inputLine.substring(7); // Extracting filename from the command
                        receiveFile(fileName, in);
                    } else {
                        out.println("500 Invalid command.");
                    }
                }
            } catch (IOException e) {
                System.err.println("Error handling client: " + e.getMessage());
            }
        }

        private void authenticate() throws IOException {
            out.println("Please enter your username:");
            String username = in.readLine();
            out.println("Please enter your password:");
            String password = in.readLine();
            authenticated = authenticateUser(username, password);
            if (authenticated) {
                out.println("230 Authentication successful. Welcome " + username + "!");
            } else {
                out.println("530 Authentication failed. Disconnecting...");
            }
        }

        private boolean authenticateUser(String username, String password) {
            // Simulated authentication - just a placeholder
            return username.equals("admin") && password.equals("admin123");
        }

        private void listFiles() {
            try {
                File directory = new File(ROOT_DIRECTORY);
                File[] files = directory.listFiles();
                if (files != null) {
                    for (File file : files) {
                        if (file.isFile()) {
                            out.println(file.getName());
                        }
                    }
                }
                out.println("226 Directory listing complete");
            } catch (Exception e) {
                out.println("550 Error listing directory");
            }
        }

        private void sendFile(String fileName) {
            try {
                File file = new File(ROOT_DIRECTORY + File.separator + fileName);
                if (file.exists()) {
                    FileInputStream fis = new FileInputStream(file);
                    BufferedInputStream bis = new BufferedInputStream(fis);
                    
                    byte[] buffer = new byte[4096];
                    int bytesRead;
                    while ((bytesRead = bis.read(buffer)) != -1) {
                        clientSocket.getOutputStream().write(buffer, 0, bytesRead);
                    }
                    bis.close();
                    fis.close();
                    
                    System.out.println("File sent: " + fileName);
                    out.println("226 Transfer complete.");
                    
                } else {
                    out.println("550 File not found.");
                }
            } catch (IOException e) {
                out.println("550 Error sending file");
            }
        }

        private void receiveFile(String fileName, BufferedReader in) {
            try {
                FileOutputStream fos = new FileOutputStream(fileName);
                BufferedOutputStream bos = new BufferedOutputStream(fos);

                byte[] buffer = new byte[4096];
                int bytesRead;

                while ((bytesRead = clientSocket.getInputStream().read(buffer)) != -1) {
                    bos.write(buffer, 0, bytesRead);
                    if (new String(buffer, 0, bytesRead).trim().equals("226 Transfer complete.")) {
                        break;
                    }
                }
                bos.close();
                fos.close();
                System.out.println("File received: " + fileName);
                
            } catch (IOException e) {
                out.println("550 Error receiving file");
            }
        }
    }
}

How can I draw a TMetafile part to a TCanvas

For some reasons I store EMF and bitmap objects in TMetafile-s, too. When I export this graphics to PDF with 300 DPI, some pictures disappear from the output. The solution : I have to cut the pictures into parts. It is a easy thing with TBitmaps bacause they have TCanvas. I have problem with TMetafile. They have no TCanvas. (MetafileCanvas just a surface to modify metafile contents, not for represent it. I divide the output size maximized to 3000 px in both directions. I have to iterate the parts. But how can I draw a TMetafile part (defined by rc : TRect) to TCanvas (with the same sizes as the rc)? I tried the cutting regions... but how could I convert the left-top coords into (0;0) in the out : TCanvas?

IDT does not invoke the page fault handler, when a page fault occurs

I found my page_fault_handler does not invoked,when page fault occurs,but double_fault_handler can be invoked.

here is my page_fault_handler

    // Definition of page_fault_handler
    pub extern "x86-interrupt" fn page_fault_handler(
        stack_frame: InterruptStackFrame,
        err_code: PageFaultErrorCode,
    ) {
        panic!(
        "EXCEPTION: PAGE FAULT, ERROR_CODE: 0x{:016x}\n\n{:#?}",
        error_code, stack_frame
    );
    }
    // Definition of double_fault_handler
    pub extern "x86-interrupt" fn double_fault_handler(
    stack_frame: InterruptStackFrame,
    error_code: u64,
) -> ! {
    panic!(
        "EXCEPTION: DOUBLE FAULT, ERROR_CODE: 0x{:016x}\n\n{:#?}",
        error_code, stack_frame
    );
}

and then I use x86_64::structures::idt to handle exception:

    // Setup for the Interrupt Descriptor Table (IDT)
    pub unsafe fn register_idt(idt: &mut InterruptDescriptorTable) {
        idt.double_fault    
            .set_handler_fn(double_fault_handler)
            .set_stack_index(gdt::DOUBLE_FAULT_IST_INDEX);
        idt.page_fault
            .set_handler_fn(page_fault_handler)
            .set_stack_index(gdt::PAGE_FAULT_IST_INDEX);
    }

here is the output of interrupt:

    check_exception old: 0xffffffff new 0xe
    214: v=0e e=0002 i=0 cpl=0 IP=0008:ffffff00000650c1 pc=ffffff00000650c1      SP=0000:ffffff01001ffdc8 CR2=ffffff0100200c18
    RAX=0000000000000000 RBX=ffffff00000cb001 RCX=0000000000000002 RDX=ffffff00000cb4c8
    RSI=0000000000000000 RDI=ffffff00008cd980 RBP=0000000000000061 RSP=ffffff01001ffdc8
    R8 =0000000000000002 R9 =0000000000000003 R10=0000000000000020 R11=0000000000000002
    R12=ffffff00008cd980 R13=0000000000000001 R14=ffffff00008cb008 R15=ffffff01001ffdd0
    RIP=ffffff00000650c1 RFL=00000202 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
    ES =0000 0000000000000000 00000000 00000000
    CS =0008 0000000000000000 ffffffff 00af9b00 DPL=0 CS64 [-RA]
    SS =0000 0000000000000000 ffffffff 00c09300 DPL=0 DS   [-WA]
    DS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
    FS =0000 0000000000000000 00000000 00000000
    GS =0000 0000000000000000 00000000 00000000
    LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
    TR =0018 ffffff00008cebc4 00000067 00008900 DPL=0 TSS64-avl
    GDT=     ffffff00008cec40 00000027
    IDT=     ffffff00008cdb90 00000fff
    CR0=80010033 CR2=ffffff0100200c18 CR3=0000000005c01000 CR4=00000668
    DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
    DR6=00000000ffff0ff0 DR7=0000000000000400
    CCS=0000000000000000 CCD=0000000000000001 CCO=EFLAGS
    EFER=0000000000000d00
    check_exception old: 0xe new 0xe
    215: v=08 e=0000 i=0 cpl=0 IP=0008:ffffff00000650c1 pc=ffffff00000650c1 SP=0000:ffffff01001ffdc8 env->regs[R_EAX]=0000000000000000
    RAX=0000000000000000 RBX=ffffff00000cb001 RCX=0000000000000002 RDX=ffffff00000cb4c8
    RSI=0000000000000000 RDI=ffffff00008cd980 RBP=0000000000000061 RSP=ffffff01001ffdc8
    R8 =0000000000000002 R9 =0000000000000003 R10=0000000000000020 R11=0000000000000002
    R12=ffffff00008cd980 R13=0000000000000001 R14=ffffff00008cb008 R15=ffffff01001ffdd0
    RIP=ffffff00000650c1 RFL=00000202 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
    ES =0000 0000000000000000 00000000 00000000
    CS =0008 0000000000000000 ffffffff 00af9b00 DPL=0 CS64 [-RA]
    SS =0000 0000000000000000 ffffffff 00c09300 DPL=0 DS   [-WA]
    DS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
    FS =0000 0000000000000000 00000000 00000000
    GS =0000 0000000000000000 00000000 00000000
    LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT
    TR =0018 ffffff00008cebc4 00000067 00008900 DPL=0 TSS64-avl
    GDT=     ffffff00008cec40 00000027
    IDT=     ffffff00008cdb90 00000fff
    CR0=80010033 CR2=ffffff0100200c18 CR3=0000000005c01000 CR4=00000668
    DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
    DR6=00000000ffff0ff0 DR7=0000000000000400
    CCS=0000000000000000 CCD=0000000000000001 CCO=EFLAGS
    EFER=0000000000000d00
    [Error]ERROR: panic occurred!

    PanicInfo {
        payload: Any { .. },
        message: Some(
            EXCEPTION: DOUBLE FAULT, ERROR_CODE: 0x0000000000000000
        
            InterruptStackFrame {
                instruction_pointer: VirtAddr(
                    0xffffff00000650c1,
                ),
                code_segment: 8,
                cpu_flags: 0x202,
                stack_pointer: VirtAddr(
                    0xffffff01001ffdc8,
                ),
                stack_segment: 0,
            },
        ),
        location: Location {
            file: "pkg/kernel/src/interrupt/exceptions.rs",
            line: 32,
            col: 5,
        },
        can_unwind: true,
        force_no_backtrace: false,
    }
    [Error]Location: pkg/kernel/src/interrupt/exceptions.rs:32
    [Error]Message: EXCEPTION: DOUBLE FAULT, ERROR_CODE: 0x0000000000000000

    InterruptStackFrame {
        instruction_pointer: VirtAddr(
            0xffffff00000650c1,
        ),
        code_segment: 8,
        cpu_flags: 0x202,
        stack_pointer: VirtAddr(
            0xffffff01001ffdc8,
        ),
        stack_segment: 0,
    }

finding I happened a page fault first,and then happened a double fault.but the page_fault_handler seemed not to be invoked at all by idt. coulud you tell me why it does not work?

Pythone reminders app code error (beginer) TypeError: can only concatenate str (not "int") to str [duplicate]

This is the coding error

runfile('C:Python Reminders app/Reminders.py', wdir='C:/Users/Python Reminders app')
Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Usersanacond/a3\Lib\tkinter\__init__.py", line 1948, in __call__
    return self.func(*args)
           ^^^^^^^^^^^^^^^^
  File "c:\users\python reminders app\reminders.py", line 67, in <lambda>
    tk.Button(self.calendar_window, text="OK", command=lambda idx=index: self.set_selected_date(idx)).pack(pady=5)
                                                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\users\python reminders app\reminders.py", line 82, in set_selected_date
    self.save_tasks()
  File "c:\users\python reminders app\reminders.py", line 31, in save_tasks
    for i, (goal_entry, deadline) in enumerate(self.goal_entries, start=1):
           ^^^^^^^^^^^^^^^^^^^^^^
  File "C:\anaconda3\Lib\tkinter\__init__.py", line 1708, in cget
    return self.tk.call(self._w, 'cget', '-' + key)
                                         ~~~~^~~~~
TypeError: can only concatenate str (not "int") to str
Exception in Tkinter callback
Traceback (most recent call last):
  File , line 1948, in __call__
    return self.func(*args)
           ^^^^^^^^^^^^^^^^
  File "c:, line 103, in done
    self.save_tasks()
  File , line 31, in save_tasks
    for i, (goal_entry, deadline) in enumerate(self.goal_entries, start=1):
           ^^^^^^^^^^^^^^^^^^^^^^
  File , line 1708, in cget
    return self.tk.call(self._w, 'cget', '-' + key)
                                         ~~~~^~~~~
TypeError: can only concatenate str (not "int") to str

It is supposed to save the data in an Excel sheet but it gives this error. I have rechecked and redone the save task but it doesn't fix anything. I know some of the extensions are unnecessary but I plan on using them in the future. The Excel file they need to go into is task.xlsx. I am a beginner at coding thus why I am here. If you need any more info for help please ask I can provide that.

This is the code:

import tkinter as tk
import tkcalendar as tkc
from tkinter import messagebox, ttk
from datetime import datetime, date, timedelta
import threading
from plyer import notification
from openpyxl import Workbook, load_workbook

class GoalApp:
    def __init__(self, master):
        self.master = master
        self.master.title("Daily Goals App")

        self.goal_entries = []  # List to store all goal entry widgets
        self.load_tasks()  # Load tasks from Excel sheet
        self.create_widgets()
   def load_tasks(self):
        try:
            workbook = load_workbook("tasks.xlsx")
            sheet = workbook.active
            for row in sheet.iter_rows(values_only=True):
                goal_entry = row[0]
                deadline = row[1]
                self.goal_entries.append((goal_entry, deadline))
            workbook.close()
        except FileNotFoundError:
            pass
    def save_tasks(self):
        workbook = Workbook()
        sheet = workbook.active
        for i, (goal_entry, deadline) in enumerate(self.goal_entries, start=1):
            sheet.cell(row=i, column=1, value=str(goal_entry))  # Convert to string
            sheet.cell(row=i, column=2, value=str(deadline))    # Convert to string
        workbook.save("tasks.xlsx")
    def create_widgets(self):
        self.goal_label = tk.Label(self.master, text="Enter Your Goals for Today:")
        self.goal_label.grid(row=0, column=0, sticky="w")

        self.add_goal_button = tk.Button(self.master, text="Add Goal", command=self.add_goal)
        self.add_goal_button.grid(row=0, column=1, padx=5)

        self.done_button = tk.Button(self.master, text="Done", command=self.done)
        self.done_button.grid(row=0, column=2, padx=5)

    def add_goal(self):
        current_row = len(self.goal_entries) + 1
    
        goal_entry = tk.Entry(self.master)
        goal_entry.grid(row=current_row, column=0, pady=5)
        self.goal_entries.append(goal_entry)

        date_button = tk.Button(self.master, text="Select Date", command=lambda idx=current_row: self.select_date(idx))
        date_button.grid(row=current_row, column=1, padx=5)

        # Add a label to display selected date next to the entry box
        selected_date_label = tk.Label(self.master, text="")
        selected_date_label.grid(row=current_row, column=2, padx=5)
        self.goal_entries[-1].selected_date_label = selected_date_label

    def select_date(self, index):
        self.calendar_window = tk.Toplevel(self.master)
        self.calendar_window.title("Select Deadline")

        self.calendar = tkc.Calendar(self.calendar_window, selectmode='day')
        self.calendar.pack(padx=10, pady=10)

        tk.Button(self.calendar_window, text="OK", command=lambda idx=index: self.set_selected_date(idx)).pack(pady=5)


    def set_selected_date(self, index):
        selected_date = self.calendar.get_date()
        if selected_date:
            try:
                date_obj = datetime.strptime(selected_date, "%m/%d/%y").date()
                formatted_date = date_obj.strftime("%Y-%m-%d")
                self.goal_entries[index - 1].deadline = formatted_date  # Store the deadline in the goal entry widget
                self.goal_entries[index - 1].selected_date_label.config(text=selected_date)  # Update the label with selected date
                self.calendar_window.destroy()
            except ValueError:
                 messagebox.showerror("Error", "Invalid date format. Please select a date from the calendar.")
        # Save tasks to Excel sheet after updating
        self.save_tasks()
    def done(self):
        self.master.iconify()  # Minimize the window

        for entry in self.goal_entries:
            goal = entry.get()
            deadline = getattr(entry, "deadline", None)

            if deadline:
                try:
                    goal_date = datetime.strptime(deadline, "%Y-%m-%d").date()
                    current_date = date.today()

                    if current_date <= goal_date:
                        days_until_deadline = (goal_date - current_date).days
                        for i in range(1, days_until_deadline + 1):
                            reminder_date = current_date + timedelta(days=i)
                            threading.Timer(30 * i, self.remind, args=[goal]).start()
                except ValueError:
                    messagebox.showerror("Error", "Invalid date format. Please use YYYY-MM-DD.")
         # Save tasks to Excel sheet after updating
         self.save_tasks()

    def remind(self, goal):
        # Calculate the time until the next day
        now = datetime.now()
        tomorrow = now.replace(hour=0, minute=0, second=0, microsecond=0) + timedelta(days=1)
        time_until_tomorrow = (tomorrow - now).total_seconds()

        # Schedule the reminder for tomorrow
        threading.Timer(time_until_tomorrow, self.remind, args=[goal]).start()

        reminder_msg = f"Don't forget to: {goal}"
        notification.notify(
            title='Reminder',
            message=reminder_msg,
            app_name='Daily Goals App',
            timeout=10  # Set the notification timeout (in seconds)
        )

        result = messagebox.askyesno("Reminder", reminder_msg + "\n\nDo you want to mark this task as done?")
    
        if result:
            messagebox.showinfo("Task Marked as Done", "You won't receive further reminders for this task.")
             return  # Stop further reminders for this task

def main():
    root = tk.Tk()
    app = GoalApp(root)
    root.mainloop()

if __name__ == "__main__":
   main()`

Can someone explain to me what "data = validated_data.copy()" means?

I wonder why the create method does not process the data directly but has to copy it into data and then process it indirectly, while the returned result is also the processed user.

class UserSerializer(serializers.ModelSerializer):
    alumni = AlumniSerializer()
    
    def to_representation(self, instance):
        req = super().to_representation(instance)
        if instance.avatar:
            req['avatar'] = instance.avatar.url
            
        if instance.cover:
            req['cover'] = instance.cover.url
        
        return req
    
    def create(self, validated_data):
        data = validated_data.copy()
        user = User(**data)
        user.set_password(user.password)
        user.save()
        
        return user
    
    class Meta:
        model = User
        fields = ['id', 'first_name', 'last_name', 'username', 'password', 'email', 'avatar', 'cover', 'alumni']
        extra_kwargs = {
            'password': {
                'write_only': True
            }
        }

WriteFile(hInputWrite, ...) has no effect C++ [closed]

I'm making a program in C++ that makes use of a pseudo-terminal using ConPTY.exe to create interactive terminal sessions. My write method to the pty is not working.

I tried googling a lot of stuff but I could get no result which could solve my problem. Even my code has no error, which makes me confused.

pty.h:

#ifndef PTY_H
#define PTY_H

#include <windows.h>
#include <string>
#include <functional>
#include <thread>

class Pty {
public:
    Pty(COORD size);
    ~Pty();
    
    bool spawn(const std::wstring& command, const std::wstring& cmdline);
    //std::string read();
    void onData(const std::function<void(const std::string&)>& callback);
    void write(const std::string& data);
    void resize(COORD size);
    void close();

private:
    HANDLE hInputRead = NULL;
    HANDLE hInputWrite = NULL;
    HANDLE hOutputRead = NULL;
    HANDLE hOutputWrite = NULL;
    HPCON hPC = NULL;

    std::function<void(const std::string&)> dataCallback;
    std::thread readThread;
    void readLoop();
};

#endif // !PTY_H

pty.cpp:

#include "pty.h"
#include <iostream>

Pty::Pty(COORD size) {
    SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, TRUE };
    if (!CreatePipe(&hOutputRead, &hOutputWrite, &sa, 0) ||
        !CreatePipe(&hInputRead, &hInputWrite, &sa, 0)) {
        std::cerr << "Failed to create pipes" << std::endl;
        return;
    }
    std::cout << "Pipes created. " << hInputRead << " && - && " << hInputWrite << std::endl;
    if (CreatePseudoConsole(size, hInputRead, hOutputWrite, 0, &hPC) != S_OK) {
        std::cerr << "Failed to create pseudo console" << std::endl;
        return;
    }
}

Pty::~Pty() {
    close();
}

bool Pty::spawn(const std::wstring& command, const std::wstring& cmdline)
{
    STARTUPINFOEX siEx;
    PROCESS_INFORMATION pi;
    ZeroMemory(&siEx, sizeof(siEx));

    siEx.StartupInfo.cb = sizeof(siEx);
    siEx.StartupInfo.hStdInput = hInputRead;
    siEx.StartupInfo.hStdOutput = hOutputWrite;
    siEx.StartupInfo.hStdError = hOutputWrite;    ZeroMemory(&pi, sizeof(pi));

    siEx.StartupInfo.dwFlags |= STARTF_USESTDHANDLES;

    // extra env setup
    WCHAR env[] = L"TERM=xterm-256color\0";
    LPWCH lpEnvironment = (LPWCH)malloc(sizeof(env));
    memcpy(lpEnvironment, env, sizeof(env));

    SIZE_T attrSize = 0;
    InitializeProcThreadAttributeList(NULL, 1, 0, &attrSize);
    siEx.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)malloc(attrSize);
    InitializeProcThreadAttributeList(siEx.lpAttributeList, 1, 0, &attrSize);
    UpdateProcThreadAttribute(siEx.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, hPC, sizeof(hPC), NULL, NULL);

    BOOL success = CreateProcessW(NULL, const_cast<LPWSTR>(cmdline.c_str()), NULL, NULL, TRUE, EXTENDED_STARTUPINFO_PRESENT | CREATE_UNICODE_ENVIRONMENT, lpEnvironment, NULL, &siEx.StartupInfo, &pi);

    if (!success) {
        std::cerr << "Failed to spawn process" << std::endl;
        return false;
    }

    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    free(lpEnvironment);
    return true;
}

void Pty::onData(const std::function<void(const std::string&)>& callback)
{
    dataCallback = callback;
    //readThread = std::thread(&Pty::readLoop, this);
    if (!readThread.joinable()) {
        readThread = std::thread(&Pty::readLoop, this);
    }
}

void Pty::readLoop()
{
    char buffer[256];
    DWORD read;
    /*while (ReadFile(hOutputRead, buffer, sizeof(buffer), &read, NULL) && read > 0) {
        buffer[read] = '\0';
        std::string data(buffer);
        if (dataCallback) {
            dataCallback(data);
        }
    }*/
    while (true) {
        BOOL result = ReadFile(hOutputRead, buffer, sizeof(buffer) - 1, &read, NULL);

        if (!result || read == 0) {
            if (GetLastError() == ERROR_BROKEN_PIPE) {
                std::cerr << "Read failed: Pipe was closed" << std::endl;
            }
            else {
                std::cerr << "Read failed: " << GetLastError() << std::endl;
            }
            break;
        }

        buffer[read] = '\0';
        std::string data(buffer, read);
        std::cout << "test - pty data: " << data << std::endl;
        if (dataCallback) {
            dataCallback(data);
        }
    }
}

void Pty::write(const std::string& data) {
    if (hInputWrite == NULL) {
        std::cerr << "Write Failed: Input handle is NULL" << std::endl;
        return;
    }

    DWORD written = 0;
    BOOL success = WriteFile(hInputWrite, data.c_str(), data.size(), &written, NULL);

    if (success) {
        FlushFileBuffers(hInputWrite);
    }

    if (!success || written != data.size()) {
        std::cerr << "Write failed: " << GetLastError() << std::endl;
    }
    else {
        std::cout << "Successfully wrote to PTY: " << data << std::endl;
    }
}

void Pty::resize(COORD size) {
    if (hPC) {
        ResizePseudoConsole(hPC, size);
    }
}

void Pty::close() {
    if (readThread.joinable()) {
        readThread.join();
    }

    if (hPC) ClosePseudoConsole(hPC);
    CloseHandle(hOutputRead);
    CloseHandle(hOutputWrite);
    CloseHandle(hInputRead);
    CloseHandle(hInputWrite);
    hPC = NULL;
}

main.cpp

#include <iostream>
#include "pty.h"
#include <windows.h>

int main()
{
    COORD size = { 80, 24 };
    Pty pty(size);

    pty.spawn(L"cmd.exe", L"cmd.exe");

    pty.write("echo Hello, World!\r\n"); // This write method doesn't work.

    pty.onData([](const std::string& data) {
        std::cout << "pty data: " << data << std::endl;
    });

    pty.close();
    
    return 0;
}

Whenever I call the write method, it always prints out a successful message, but it takes no effect.

R Survfit shows lower OS than PFS while data seems correct

I've tried to create a Kaplan Meier Analysis and get the 4 year PFS and OS. For some reason, the output is a lower OS at 1460 days (0.518) than PFS (0.546). Where is my mistake?

library(survival)
library(readxl)
library(survminer)
CTrial <- read_excel("trial 2023.xlsx",sheet = 2)

# Fit Kaplan-Meier survival curve
fit <- survfit(Surv(PFSMonth, Event_PFS) ~ 1, data = CTrial)
summary(fit)
fit <- survfit(Surv(OSMonth, Event_OS) ~ 1, data = CTrial)

##followed by a + if the subject was censored. Letโ€™s look at the first 10 observations:
##PFS
time <- CTrial$PFS
event <- CTrial$Event_PFS
Surv(time, event)[1:33]
summary(survfit(Surv(time, event) ~ 1, data = CTrial), times = 1460)

##OS
time <- CTrial$OS
event <- CTrial$Event_OS
Surv(time, event)[1:33]
summary(survfit(Surv(time, event) ~ 1, data = CTrial), times = 1460)

I already tried to analyze the data for possible entry errors, but it does not seem off.

These are the outputs from Surv(time, event)[1:33], + is censored:

These are the outputs from Surv(time, event)[1:33], + is censored

Thanks so much!

Calculating rotation angle of each path on a svg circle chart

https://jsfiddle.net/p4d57e8x/3/

const getArcPath = (start, end, innerRadius, outerRadius) => {
    const startAngle = start * Math.PI * 2;
    const endAngle = end * Math.PI * 2;
    const x1 = innerRadius * Math.sin(startAngle);
    const y1 = innerRadius * -Math.cos(startAngle);
    const x2 = outerRadius * Math.sin(startAngle);
    const y2 = outerRadius * -Math.cos(startAngle);
    const x3 = outerRadius * Math.sin(endAngle);
    const y3 = outerRadius * -Math.cos(endAngle);
    const x4 = innerRadius * Math.sin(endAngle);
    const y4 = innerRadius * -Math.cos(endAngle);
    const bigArc = end - start >= 0.5;
    const outerFlags = bigArc ? '1 1 1' : '0 0 1';
    const innerFlags = bigArc ? '1 1 0' : '1 0 0';
    return `M ${x1},${y1} L ${x2},${y2} A ${outerRadius} ${outerRadius} ${outerFlags} ${x3},${y3} 
        L ${x4},${y4} A ${innerRadius} ${innerRadius} ${innerFlags} ${x1},${y1} Z`;
};

This is the code for the path itself, and all of the paths they create a circle.

I am not sure how to get the rotation angle for each path in the circle (say there is red, green, blue, purple), I've tried many things but this seems more of a math problem more than anything else.

I tried a bunch of random code I found, this for example

const getRotationAngle = (start, end) => {
    const startAngle = start * 360;
    const endAngle = end * 360; 
    return (startAngle + endAngle) / 2;
};
``` but it doesn't work of course because it's just gibberish for me and I have no idea what I even need to calculate to get the angle.
โŒ
โŒ