beginner – Comma Code (from Automate the Boring Stuff)

I’ve read some other people’s answers here but I’m confused why that level of complexity is necessary. Could anyone tell why the the following code does not fulfill the task? Thanks 🙂

def task(first, second, third, fourth):
print(first + ", " + second + ", " + third + ", and " + fourth)
spam = ("lemon", "orange", "coffee", "dogs")
task(spam(0), spam(1), spam(2), spam(3))

database – website creation for beginner

I am looking to create a website for a online game I play. This website should enable to help players find trades (and allow me to learn doing something fun).

Basicly it’s like a auction website. A user post their ‘rescource’ that they would like to trade. and players can bid.

I can write a windows application for this in jippy using vb.net; but I am looking to make a website for this. I have access to Mysql db.

Does anyone can give some pointers where to start? Maybe some good tutorials?

Best regards,

beginner – Random index generator in C++

I have a training dataset from which I want to draw samples in a random fashion such that all samples are used before getting randomly shuffled again. For this reason I implemented a simple random index generator.

For a dataset of 10 samples, the output looks something like this:

0 1 2 3 4 5 6 7 8 9 
4 3 7 8 0 5 2 1 6 9 
0 5 7 8 4 3 9 2 1 6 
5 7 6 3 8 4 2 0 1 9 
4 6 0 2 8 1 3 9 5 7 
4 0 5 1 7 9 6 2 8 3 
3 8 5 6 1 7 2 4 0 9 
0 4 6 2 9 5 8 3 1 7 
1 3 6 8 2 7 5 9 0 4 
5 1 7 9 8 0 6 4 2 3 

I would appreciate advice especially in the following areas:

  • Code style (readability, naming conventions, etc…)
  • Class design
  • Efficiency (how to avoid unnecessary complexity)
  • Reinventing the wheel (does the STL offer functionality that I should use?)
  • Are there perhaps bugs that I am not seeing right now?

Please be as hard as possible with this implementation and give me constructive feedback.

main.cpp

#include <iostream>
#include "random_index.hpp"

int main() {
    unsigned int size = 10;
    RandomIndex rand_idx(size);

    unsigned int n = 0;
    for (unsigned int i=0; i<100; ++i, ++n) {
        std::cout << rand_idx.get_index() << ' ';
        if ((n+1) % size == 0) {
            std::cout << 'n';
        }
    }

    std::cout << 'n';
}

random_index.cpp

#include "random_index.hpp"

RandomIndex::RandomIndex(unsigned int _size) {
    size = _size;
    index.resize(_size, 0);
    std::iota(index.begin(), index.end(), 0);
}

unsigned int RandomIndex::get_index() {
    if (counter < size) {
        return index(counter++);
    } else {
        counter = 0;
        std::random_shuffle(index.begin(), index.end());
        return index(counter++);
    }
}

random_index.hpp

#ifndef RANDOM_INDEX_H
#define RANDOM_INDEX_H

#include <vector>
#include <numeric>
#include <algorithm>

class RandomIndex {
    
    public:
        RandomIndex(unsigned int _size);
        unsigned int get_index();
    
    private:
        unsigned int size;
        unsigned int counter = 0;
        std::vector<unsigned int> index;

};

#endif

I compiled the code using the following command:

g++ -O -Wall main.cpp random_index.cpp 

how to choose best web hosting as a beginner?

hello friends, I’m a beginner at website making, how do I choose the best web hosting? help me… | Read the rest of https://www.webhostingtalk.com/showthread.php?t=1834593&goto=newpost

beginner – Basic Cpp TCP TLS Client-Server hashing code based on OpenSSL1.1.1 (detailed instruction included)

I wrote ‘Client.cpp’ and ‘Client.cpp’ that do the following.
This is a part of the graduate research assistant screening process.

  1. Create a client and server program communicating over TCP socket.
  2. Establish TLS connection between the client and server
  3. Implement a hash service on the server
  • Take a number from the client
  • Send this number over TLS to the server
  • The server uses the Sha256 hash function within the OpenSSL library to generate a hash code for the number
  • The server sends the hash code back to the client for display.

Any opinion including the following is welcomed:

  • Application of best practices and design pattern usage
  • Potential security issues
  • Performance
  • Correctness in unanticipated cases
  • Scalability
  • Formatting

Code was developed and tested using

  • Ubuntu 20.04
  • OpenSSL 1.1.1
  • g++ 7.5.0

1. install openssl-1.1.1i

1.1. download openssl-1.1.1i here : https://www.openssl.org/source/

1.2 You may follow this instruction on how to install openssl : https://askubuntu.com/questions/1102803/4.how-to-upgrade-openssl-1-1-0-to-1-1-1-in-ubuntu-18-04

NOTE : after download, change ‘openssl-1.1.1g’ into ‘openssl-1.1.1i’

2. Secure a certificate and a private key

Do 2.1 or 2.2

2.1. create your own certificate

openssl req -new -x509 -nodes -config ssl.conf -out cert.pem -keyout key.pem -days 365

ssl.conf is uploaded.

For more information on how to create certificates, see: https://linuxize.com/post/creating-a-self-signed-ssl-certificate/

2.2 use uploaded certificate (cert.pem) and a private key (key.pem)

I know a private key should not be shared. This is only for convenient testing.

3. run code

(Server)

g++ -Wall -o Server Server.cpp -lssl -lm -lcrypto 
I uploaded 'Server'. Therefore, you may skip it. This is only for convenient testing. 

./Server (port) (cert.pem's path) (private key.pem's path) (the number of clients are allowed to request connection) 
./Server 9876 ./cert.pem ./ket.pem 5 

(Client)

g++ -Wall -o Client Client.cpp -lssl -lm -lcrypto 
I uploaded 'Server'. Therefore, you may skip it. This is only for convenient testing. 

./Server (hostname) (port) 
./Client 127.0.0.1 9876 
You can see results in localhost if you enter 127.0.0.1.

You must start Server first. 
The Server's port and the Client's port must be identical. 

reference

  1. socket programming in cpp: https://www.geeksforgeeks.org/socket-programming-cc/
  2. how to compile and debug cpp file in visual studio code : https://code.visualstudio.com/docs/cpp/config-linux
  3. TLS Server : https://wiki.openssl.org/index.php/Simple_TLS_Server
  4. TLS Client : https://gist.github.com/vedantroy/d2b99d774484cf4ea5165b200888e414
  5. openssl and compile : https://stackoverflow.com/questions/8945963/compile-c-and-openssl-on-ubuntu-11-10
  6. code with code review : Send and receive data code using OpenSSL
  7. sha256 : https://stackoverflow.com/questions/2262386/generate-sha256-with-openssl-and-c

Server.cpp

#include <iostream> 
#include <unistd.h> 
#include <string.h>
#include <iomanip>
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <openssl/ssl.h>
#include <openssl/err.h>
using namespace std;

SSL_CTX *configure_context() { 
    if(OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL) != 1){
        perror("OPENSSL_init_ssl() failed");
        exit(EXIT_FAILURE);
    }

    const SSL_METHOD *method = SSLv23_server_method();
    if(method == NULL) {
        perror("SSLv23_server_method() failed");
        exit(EXIT_FAILURE);
    }

    // create SSL context
    SSL_CTX *ctx = SSL_CTX_new(method);
    if (!ctx) {
        perror("SSL_CTX_new() failed");
        exit(EXIT_FAILURE);
    }

    // SSL_CTX_set1_curves() sets the supported curves for ctx to clistlen curves in the array clist.
    if(SSL_CTX_set_ecdh_auto(ctx, 1) != 1) {
        perror("SSL_CTX_set_ecdh_auto() failed");
        exit(EXIT_FAILURE);
    }

    return ctx;
}

void configure_keys(SSL_CTX *ctx, char *certificate, char *private_key) {
    if (SSL_CTX_use_certificate_file(ctx, certificate, SSL_FILETYPE_PEM) <= 0) {
        perror("SSL_CTX_use_certificate_file() failed");
        exit(EXIT_FAILURE);
    }

    if (SSL_CTX_use_PrivateKey_file(ctx, private_key, SSL_FILETYPE_PEM) <= 0) {
        perror("SSL_CTX_use_PrivateKey_file() failed");
        exit(EXIT_FAILURE);
    }
}

string sha256(const string input) {
    unsigned char hash(SHA256_DIGEST_LENGTH);
    SHA256_CTX sha256;

    // initialize a SHA256_CTX structure.
    if(SHA256_Init(&sha256) != 1) {
        perror("SHA256_Init() failed");
        exit(EXIT_FAILURE);
    }

    // SHA256_Update() is called repeatedly with chunks of the message to be hashed (input.c_str() bytes at input.size()).
    if(SHA256_Update(&sha256, input.c_str(), input.size()) != 1) {
        perror("SHA256_Update() failed");
        exit(EXIT_FAILURE);
    }

    // SHA256_Final() places the message digest in 'hash', 
    // which must have space for SHA256_DIGEST_LENGTH (32) bytes of output, and erases the SHA256_CTX.
    if(SHA256_Final(hash, &sha256) != 1) {
        perror("SHA256_Final() failed");
        exit(EXIT_FAILURE);
    }

    stringstream hash_code;
    for(int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
        hash_code << hex << setw(2) << setfill('0') << (int)hash(i);
    }
    return hash_code.str();
}

int main(int argc, char *argv()) { 
    SSL_CTX *ctx = configure_context();

    configure_keys(ctx, argv(2), argv(3));

    // create a client and server program communicating over TCP socket
    // create a TCP socket
    int server_socket = socket(PF_INET, SOCK_STREAM, 0);
    if (server_socket < 0) {
        perror("socket() failed");
        exit(EXIT_FAILURE);
    }
    cout << "(current state) socket()" << endl;

    struct sockaddr_in server_address;
    memset(&server_address, 0, sizeof(server_address));
    server_address.sin_family = AF_INET;
    // convert 4 byte-integer into network bytes
    server_address.sin_addr.s_addr = htonl(INADDR_ANY);
    // convert 2 byte-integer into network bytes
    server_address.sin_port = htons(atoi(argv(1)));

    if (bind(server_socket, (struct sockaddr *)&server_address, sizeof(server_address)) < 0) {
        perror("bind() failed");
        exit(EXIT_FAILURE);
    }
    cout << "(current state) bind()" << endl;

    if (listen(server_socket, atoi(argv(4))) < 0) {
        perror("listen() failed");
        exit(EXIT_FAILURE);
    }
    cout << "(current state) listen()" << endl;

    // server waits for Client to connect
    while (1) {
        char input(1024) = { 0 };
        char output(1024) = { 0 }; 

        struct sockaddr_in client_address;
        int size_client_address = sizeof(client_address);
        int client_socket = accept(server_socket, (struct sockaddr *)&client_address, (socklen_t *)&size_client_address);
        if (client_socket < 0) {
            perror("accept() failedn");
            exit(EXIT_FAILURE);
        }
        cout << "(current state) accept()" << endl;

        // establish TLS connection between the client and server
        SSL *ssl = SSL_new(ctx);
        if (ssl == nullptr) {
            perror("SSL_new() failedn");
            exit(EXIT_FAILURE);
        }        

        if(SSL_set_fd(ssl, client_socket) != 1) {
            perror("SSL_set_fd() failedn");
            exit(EXIT_FAILURE);
        }

        if (SSL_accept(ssl) <= 0) {
            perror("SSL_accept() failedn");
            continue;
        }

        // get a number from Client
        int read_length = SSL_read(ssl, (char *)input, 1024);
        if (read_length <= 0) {
            perror("SSL_read() failedn");
            continue;
        }

        if (strcmp(input, "(exit)") == 0) {
            cout << "(terminate server)" << endl;
            SSL_free(ssl);
            close(client_socket);
            break;
        }

        // implement a hash service on the server 
        // the server uses the Sha256 hash function within the OpenSSL library to generate a hash code for the number 
        string hash_code = sha256(input);

        // the server sends the hash code back to the client for display. 
        int length = sprintf(output, "(server's hash code): %s", hash_code.c_str());
        int written_length = SSL_write(ssl, output, length);
        if (written_length <= 0) {
            perror("SSL_write() failedn");
            continue;
        } 
        cout << output << endl;
        
        // shut down a TLS/SSL connection
        if(SSL_shutdown(ssl) != 1) {
            perror("SSL_shutdown() failedn");
        }
        // free an allocated SSL structure
        SSL_free(ssl);
        close(client_socket);
    } 

    close(server_socket);
    SSL_CTX_free(ctx);
    // load and free error strings
    ERR_free_strings(); 

    return 0;
}

Client.cpp

#include <iostream>
#include <unistd.h> 
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h> 
#include <netdb.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

using namespace std;

const int ERROR_STATUS = -1;

SSL_CTX *configure_context() {
    const SSL_METHOD *method = TLS_client_method();
    if (method == NULL) {
        perror("TLS_client_method() failedn");
        exit(EXIT_FAILURE);
    }

    SSL_CTX *ctx = SSL_CTX_new(method);
    if (ctx == NULL) {
        perror("SSL_CTX_new() failedn");
        exit(EXIT_FAILURE);
    }
    return ctx;
}

void display_certs(SSL *ssl) {
    // get server's certificate
    X509 *cert = SSL_get_peer_certificate(ssl); 
    if (cert == nullptr) {
        perror("SSL_get_peer_certificate() failed. No client certificates configuredn");
        exit(EXIT_FAILURE);
    }

    cout << "(server certificates)" << endl;
    char *line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
    if(line == NULL) {
        perror("X509_NAME_oneline(X509_get_subject_name(), 0, 0) failedn");
        exit(EXIT_FAILURE);
    }
    cout << "subject: " << line << endl;
    delete line;

    line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
    if(line == NULL) {
        perror("X509_NAME_oneline(X509_get_issuer_name(), 0, 0) failedn");
        exit(EXIT_FAILURE);
    }
    cout << "issuer: " << line << endl;
    delete line;

    X509_free(cert);
}

int main(int argc, char *argv()) {
    cout << "enter (exit) to end this program" << endl;

    SSL_CTX *ctx = configure_context(); 

    // create an SSL structure for a connection
    SSL *ssl = SSL_new(ctx);
    if (ssl == NULL) {
        perror("SSL_new() failedn");
        exit(EXIT_FAILURE);
    } 

    struct hostent *host = gethostbyname(argv(1));
    if (host == nullptr) {
        perror("gethostbyname() failedn");
        exit(EXIT_FAILURE);
    }

    struct addrinfo hints = {0}, *addrs;
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    if (getaddrinfo(argv(1), argv(2), &hints, &addrs) != 0) {
        perror("getaddrinfo() failedn");
        exit(EXIT_FAILURE);
    }

    int client_socket;
    for (struct addrinfo *addr = addrs; addr != nullptr; addr = addr->ai_next) {
        client_socket = socket(addrs->ai_family, addrs->ai_socktype, addrs->ai_protocol);
        if (client_socket == ERROR_STATUS) {
            perror("perror() failedn");
            continue;
        }
        cout << "(current state) socket()n";

        if (connect(client_socket, addr->ai_addr, addr->ai_addrlen) == 0) {
            cout << "(current state) connect()" << endl;
            break; 
        }

        client_socket = ERROR_STATUS;
        close(client_socket);
    }

    freeaddrinfo(addrs);

    if (client_socket == ERROR_STATUS) {
        perror("connect() failedn");
        exit(EXIT_FAILURE);
    }

    // connect the SSL object (ssl) with a file descriptor (client_socket)
    if (SSL_set_fd(ssl, client_socket) != 1) {
        perror("SSL_set_fd() failedn");
        exit(EXIT_FAILURE);
    }

    // initiate the TLS/SSL handshake with an TLS/SSL server
    if (SSL_connect(ssl) != 1) {
        perror("SSL_connect() failedn");
        exit(EXIT_FAILURE);
    }
    cout << "(current state) connected with " << SSL_get_cipher(ssl) << " encryption" << endl;

    // print certificate information which is set by Server
    // I added this to make sure certificate is applied
    display_certs(ssl);

    while (1) {
        // take a number from client
        cout << "(enter a number): ";
        string sent;
        getline(cin, sent);
        if (sent == "") {
            continue;
        }

        // send this number over TLS to the server
        int written_length = SSL_write(ssl, sent.c_str(), sent.length());
        if (written_length <= 0) {
            SSL_get_error(ssl, written_length);
            continue;
        }

        if (strcmp(sent.c_str(), "(exit)") == 0) {
            cout << "(terminate client)" << endl;
            break;
        }

        // a stack can only hold 1024 kilobytes of data
        // to avoid the risk of a stack-overflow, I set array size 1024 
        char input(1024) = { 0 };
        int read_length = SSL_read(ssl, (char *)input, 1024);
        if (read_length <= 0) {
            SSL_get_error(ssl, read_length);
            continue;
        }
        cout << input << endl;
        break;
    }

    close(client_socket);
    SSL_CTX_free(ctx);

    return 0;
}

beginner – Basic python GUI Calculator using tkinter

Could anyone review my code for a calculator using tkinter?

I’m attempting to use two classes, one with the functions of the calculator and a second which creates the GUI.

It seems to work fine (although I’d like to add keyboard functionality), so I’d like to ask if there is anything that I could have done better. The code is based on a tutorial I found online. The algorithm for evaluate is also found online, but I modified it to work with the program.

My program about 400 lines, so I really think there might be some way to improve it?

The tutorial is here

The original evaluation code is here

Here’s my code..

import tkinter as tk  # Import tkinter library
import math  # Import math lib
import re  # Import this thing too


class Calculator:
    """
    A class used to implement the functions of a calculator
    """

    def __init__(self):
        self.answer = tk.StringVar()
        self.equation = tk.StringVar()
        self.expression = ""
        self.paren = False
        self.prev_expression = ()
        self.itr = ""

    def set_prev_expr(self):
        """
        Stores all changes to the expression in a list
        """
        self.prev_expression.append(self.expression)

    def get_prev_expr(self):
        try:
            print("Getting last entry")
            self.expression = self.prev_expression.pop()
            self.equation.set(self.expression)
        except IndexError:
            print("No values in undo")
            self.answer.set("Can't undo")

    def clear(self):
        """
        Resets Variables used to defaults
        """
        self.set_prev_expr()
        print("Clearing")
        self.paren = False
        self.expression = ""
        self.answer.set(self.expression)
        self.equation.set(self.expression)
        self.itr = ""
        print("Clearing complete")

    def insert_paren(self):
        """
        Inserts paren into equation
        """
        self.set_prev_expr()
        if not self.paren:
            self.expression += "("
            self.equation.set(self.expression)
            self.paren = True  # Keeps track of paren orientation
            print(self.expression)
        else:
            self.expression += ")"
            self.paren = False
            self.equation.set(self.expression)
            print(self.expression)

    def percent(self):
        """
        divides expression by 100
        """
        self.set_prev_expr()
        self.expression += " / 100"
        self.evaluate(self.expression)

    def square(self):
        self.set_prev_expr()
        if True:  # If the last number is in paren applies to entire paren block
            match = re.findall('((^))*)|((^))*)|"(^")*"|S+', self.expression)
            print(match)
            try:
                last = float(self.evaluate(match.pop(-1)))
                self.expression = " ".join(match) + " " + str(math.pow(last, 2))  # Always pos, no chance of dash causing error
                print(self.expression)
                self.evaluate(self.expression)
            except:  # Any errors should be picked up by evaluate function so no need to print to screen
                print("Error")
                self.answer.set("Cannot Calculate Ans")

        

    def press(self, num: str):
        self.set_prev_expr()
        if num in ("*", "/", "+", "-"):  # Adds spaces either side of operators. Special operators are handled separately
            self.expression = str(self.expression) + " " + str(num) + " "
        else:  # Negative is included here
            self.expression = str(self.expression) + str(num)
        self.equation.set(self.expression)
        print(self.expression)

    def square_root(self):
        self.set_prev_expr()
        if True:  # If the last number is in paren applies to entire paren block
            match = re.findall('((^))*)|((^))*)|"(^")*"|S+', self.expression)
            print(match)
            try:
                last = float(self.evaluate(match.pop(-1)))
                self.expression = " ".join(match) + " " + str(math.sqrt(last))
                print(self.expression)
                self.evaluate(self.expression)
            except ValueError:  # Should be called if try negative num
                print("Error")
                self.answer.set("Imaginary Answer")

    def backspace(self):
        self.set_prev_expr()
        if self.expression(-1) == ")":  # If you delete a paren re-add paren flag
            self.paren = True
        self.expression = self.expression(:-1)
        print(self.expression)
        self.equation.set(self.expression)

    # Function to find weight
    # of operators.
    def _weight(self, op):
        if op == '+' or op == '-':
            return 1
        if op == '*' or op == "https://codereview.stackexchange.com/":
            return 2
        return 0

    # Function to perform arithmetic
    # operations.
    def _arith(self, a, b, op):
        try:
            if op == '+':
                return a + b
            elif op == '-':
                return a - b
            elif op == '*':
                return a * b
            elif op == "https://codereview.stackexchange.com/":
                return a / b
            else:
                return None
        except ZeroDivisionError:
            print("Invalid Operation: Div by Zero")
            self.answer.set("ZeroDivisionError")
            return "ZeroDiv"

    # Function that returns value of
    # expression after evaluation.
    def evaluate(self, tokens: str):
        self.set_prev_expr()
        
        # adds support for negative numbers by adding a valid equation
        token_lst = tokens.split(" ")
        #print(token_lst)
        for index, elem in enumerate(token_lst):
            if "—" in elem:
                token_lst(index) = elem.replace("—", "(0 -") + ")" 
        #print(token_lst)
        tokens = " ".join(token_lst)
        print(tokens)
        
        # stack to store integer values.
        values = ()

        # stack to store operators.
        ops = ()
        i = 0

        while i < len(tokens):

            # Current token is a whitespace,
            # skip it.
            if tokens(i) == ' ':
                i += 1
                continue

            # Current token is an opening 
            # brace, push it to 'ops'
            elif tokens(i) == '(':
                ops.append(tokens(i))

            # Current token is a number or decimal point, push 
            # it to stack for numbers.
            elif (tokens(i).isdigit()) or (tokens(i) == "."):
                val = ""

                # There may be more than one
                # digits in the number.
                while (i < len(tokens) and
                       (tokens(i).isdigit() or tokens(i) == ".")):
                    val += str(tokens(i))
                    i += 1
                val = float(val)
                values.append(val)

                # right now the i points to 
                # the character next to the digit,
                # since the for loop also increases 
                # the i, we would skip one 
                #  token position; we need to 
                # decrease the value of i by 1 to
                # correct the offset.
                i -= 1

            # Closing brace encountered, 
            # solve entire brace.
            elif tokens(i) == ')':

                while len(ops) != 0 and ops(-1) != '(':
                    try:
                        val2 = values.pop()
                        val1 = values.pop()
                        op = ops.pop()
                    except IndexError:
                        print("Syntax Error")
                        self.answer.set("Syntax Error")
                        self.get_prev_expr()
                        self.get_prev_expr()  # Returns expr to previous state
                        return None

                    values.append(self._arith(val1, val2, op))
                    if values(-1) == "ZeroDiv":
                        return None

                # pop opening brace.
                ops.pop()

            # Current token is an operator.
            else:

                # While top of 'ops' has same or 
                # greater _weight to current 
                # token, which is an operator. 
                # Apply operator on top of 'ops' 
                # to top two elements in values stack.
                while (len(ops) != 0 and
                       self._weight(ops(-1)) >=
                       self._weight(tokens(i))):

                    try:
                        val2 = values.pop()
                        val1 = values.pop()
                        op = ops.pop()
                    except IndexError:
                        print("Syntax Error")
                        self.answer.set("Syntax Error")
                        self.get_prev_expr()  # Returns expr to previous state
                        self.get_prev_expr()
                        return None

                    values.append(self._arith(val1, val2, op))
                    if values(-1) == "ZeroDiv":
                        return None

                # Push current token to 'ops'.
                ops.append(tokens(i))

            i += 1

        # Entire expression has been parsed 
        # at this point, apply remaining ops 
        # to remaining values.
        while len(ops) != 0:

            try:
                val2 = values.pop()
                val1 = values.pop()
                op = ops.pop()
            except IndexError:
                print("Syntax Error")
                self.answer.set("Syntax Error")
                self.get_prev_expr()  # Returns expr to previous state
                self.get_prev_expr()
                return None

            values.append(self._arith(val1, val2, op))
            if values(-1) == "ZeroDiv":
                return None

        # Top of 'values' contains result,
        # return it.
        try:
            if (values(-1) % 1 == 0):  # Checks if the value has decimal
                values(-1) = int(values(-1))
            if (values(-1) >= 9.9e+8) or (values(-1) <= -9.9e+8):
                raise OverflowError
            values(-1) = round(values(-1), 10)  # rounds a decimal number to 10 digits (max on screen is 20)
            self.expression = str(values(-1))
            self.expression = self.expression.replace("-", "—")  # If the answer starts with a dash replace with neg marker
            self.equation.set(self.expression)
            self.answer.set(self.expression)

            return values(-1)
        except SyntaxError:
            print("Syntax Error")
            self.answer.set("Syntax Error")
            return None
        except OverflowError:
            print("Overflow")
            self.answer.set("Overflow")
            self.get_prev_expr() #Returns to previous state (for special funct) deletes extra step in normal ops
            self.get_prev_expr()
            return None


class CalcGui(Calculator):
    
    BOX_HEIGHT = 2
    BOX_WIDTH = 8
    CLEAR_COLOR = "#c2b2b2"
    SPECIAL_BUTTONS_COLOR = "#b1b1b1"
    OPERATOR_COLOR = "dark grey"
    NUM_COLOR = "#cfcaca"
 
    def __init__(self, main_win: object):
        self.main_win = main_win
        Calculator.__init__(self)
        self.create_text_canvas()
        self.create_button_canvas()

    def create_text_canvas(self):
        entry_canv = tk.Canvas(bg="blue")  # Contains the output screens
        entry1 = tk.Entry(entry_canv,
                          text=self.equation,
                          textvariable=self.equation,
                          width=20
                          )
        entry1.pack()

        ans_box = tk.Label(entry_canv,
                           textvariable=self.answer,
                           width=20
                           )
        ans_box.pack()

        entry_canv.pack()
    
    def create_button_canvas(self):
        self.buttons = (  # List of all button info
             #chr.    x  y  color                     command
            ("clear", 0, 0, self.CLEAR_COLOR          , self.clear             ),
            ("↺"   , 1, 0, self.SPECIAL_BUTTONS_COLOR, self.get_prev_expr     ),
            ("x²"   , 2, 0, self.SPECIAL_BUTTONS_COLOR, self.square            ),
            ("√x"   , 3, 0, self.SPECIAL_BUTTONS_COLOR, self.square_root       ),
            ("—"    , 0, 1, self.SPECIAL_BUTTONS_COLOR, lambda: self.press("—")),
            ("()"   , 1, 1, self.SPECIAL_BUTTONS_COLOR, self.insert_paren      ),
            ("%"    , 2, 1, self.SPECIAL_BUTTONS_COLOR, self.percent           ),
            ("÷"    , 3, 1, self.OPERATOR_COLOR       , lambda: self.press("/")),
            ("7"    , 0, 2, self.NUM_COLOR            , lambda: self.press("7")),
            ("8"    , 1, 2, self.NUM_COLOR            , lambda: self.press("8")),
            ("9"    , 2, 2, self.NUM_COLOR            , lambda: self.press("9")),
            ("x"    , 3, 2, self.OPERATOR_COLOR       , lambda: self.press("*")),
            ("4"    , 0, 3, self.NUM_COLOR            , lambda: self.press("4")),
            ("5"    , 1, 3, self.NUM_COLOR            , lambda: self.press("5")),
            ("6"    , 2, 3, self.NUM_COLOR            , lambda: self.press("6")),
            ("-"    , 3, 3, self.OPERATOR_COLOR       , lambda: self.press("-")),
            ("1"    , 0, 4, self.NUM_COLOR            , lambda: self.press("1")),
            ("2"    , 1, 4, self.NUM_COLOR            , lambda: self.press("2")),
            ("3"    , 2, 4, self.NUM_COLOR            , lambda: self.press("3")),
            ("+"    , 3, 4, self.OPERATOR_COLOR       , lambda: self.press("+")),
            ("⌫"   , 0, 5, self.NUM_COLOR            , self.backspace         ),
            ("0"    , 1, 5, self.NUM_COLOR            , lambda: self.press("0")),
            ("."    , 2, 5, self.NUM_COLOR            , lambda: self.press(".")),
            ("="    , 3, 5, "orange"             , lambda: self.evaluate(self.expression)),
            )

        button_canv = tk.Canvas(bg="red")  # Contains Input buttons
        for (character, x, y, color, command) in self.buttons:
            button = tk.Button(button_canv, text= character, bg= color,  # Unique
                               relief= tk.RAISED, height= self.BOX_HEIGHT, width= self.BOX_WIDTH)  # Defaults
            button.grid(row= y, column= x)
            button.configure(command= command)
        button_canv.pack(padx=5, pady=5)


def main():
    main_win = tk.Tk()
    main_win.configure(background="light blue")
    main_win.title("Calculator")
    main_win.resizable(False, False)  # Becomes ugly if you resize it
    calculator = CalcGui(main_win)
    main_win.mainloop()


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

Am a beginner and I want to get an API template on banking website, with the features of Crypto trading in it

Please kindly help with an API template on a banking website that will have features for Crypto trading too

Beginner C fgetline() implementation – Code Review Stack Exchange

I am doing C coding practice by reinventing a getline function that works with any streams. Any comments on the overall code quality, including correctness, style and performance, are greatly appreciated.

fgetln.h:

#include <stdio.h>

char *fgetln(FILE *fp);
/* 
 * Read a line from fp, dynamically allocate memory and store it as a string.
 * The 'n' at the end of the line and any '' before are discarded. Return
 * a pointer to the string when successful; return NULL if the line is empty
 * or an error occurs.
 *
 * This function implements the "callee allocates, caller frees" model. You
 * should pass the returned pointer to free() when it is no longer needed.
 */

fgetln.c:

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdint.h>

#define EXPAND_RATIO 2
// Aggressiveness of memory expansion, must be an integer ≥ 2.

char *fgetln(FILE *fp)
{
    signed char c;

    // Look for hints of an empty line and discard any '' at the start.
    while (true) {
        c = getc(fp);
        if (c == '') continue;
        if (c == 'n' || c == EOF) return NULL;
        break;
    }

    // If we have reached here, the line has content in it.
    ungetc(c, fp);

    char *p_tmp, *line = NULL;
    size_t arr_size = sizeof(char);
    bool end_of_line = false;
    unsigned long long i = 0;

    p_tmp = realloc(line, arr_size);
    if (p_tmp == NULL) goto err_cleanup;
    line = p_tmp;

    do {
        c = getc(fp);
        if (c == '') continue;
        if (c == 'n' || c == EOF) {
            end_of_line = true;
            c = '';
        }

        if ((i * sizeof(char)) == arr_size) {
            if (arr_size == SIZE_MAX) {
                if (c != '') goto err_cleanup;  // Too long
            } else {
                // Assuming SIZE_MAX % sizeof(char) == 0.
                arr_size = arr_size > (SIZE_MAX / EXPAND_RATIO)
                         ? SIZE_MAX
                         : arr_size * EXPAND_RATIO;
                p_tmp = realloc(line, arr_size);
                if (p_tmp == NULL) goto err_cleanup;
                line = p_tmp;
            }
        }

        line(i++) = c;
    } while (!end_of_line);

    // Shorten the string to its logical size if available.
    size_t logic_size = i * sizeof(char);

    if (logic_size < arr_size) {
        p_tmp = realloc(line, logic_size);
        if (p_tmp == NULL) goto err_cleanup;
        line = p_tmp;
    }
    return line;

err_cleanup:
    free(line);
    return NULL;
}

#undef EXPAND_RATIO

beginner – Insertion Sort (translated psuedocode) in Ruby

I’m a new programmer and I’m periodically going into the Intro To Algorithms CLRS textbook and trying to translate pseudocode into Ruby for skill practice. This is my implementation/translation of insertion sort.

I’m looking for feedback on readability as well as efficiency.

Pseudocode is found on page 17 of Intro To Algorithms Second Edition just in case you happen to have it lying around, more interested in the feedback just on the code itself.

class InsertionSort
    attr_accessor :arr
    def initialize(arr)
      @arr = arr
    end
    
    def sort
      key = 1
      to_the_left = key - 1
      
      while key < self.arr.length
        if arr(key) < arr(to_the_left) 
          
          mover_key = key
          left_ele_moving_right = to_the_left
          
          until arr(mover_key) > arr(left_ele_moving_right) || left_ele_moving_right < 0
            
            arr(left_ele_moving_right), arr(mover_key) = 
            arr(mover_key), arr(left_ele_moving_right)
              
              mover_key -= 1 
              left_ele_moving_right -= 1
          end
        end
        
        key += 1
        to_the_left += 1
      end
      
      self.arr
    end
end

```