php – OOP: The correct use of classes and optimizing code

I am trying to improved my coding skills. I mainly work in web development. I had a “system” that I use in all my projects to fetch data from my DB to the browser. I tried an implementation of OOP, it works fine, but I dont think I did it correctly.

How can I optimized this code to make full use of an OOP design?

<?php
  class DBX{

    //---------------USER-----------------------------

    static function GetUserByEmail($email){
      $link = openlink();
      $query = "SELECT * FROM users WHERE email = ? LIMIT 1";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      }else {
        mysqli_stmt_bind_param($stmt, "s", $email);
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $resultArray = $result->fetch_assoc();
          $finalTest = $resultArray;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }

    static function GetUserByID($id){
      $link = openlink();
      $query = "SELECT * FROM users WHERE user_id = ? LIMIT 1";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      }else {
        mysqli_stmt_bind_param($stmt, "i", $id);
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $resultArray = $result->fetch_assoc();
          $finalTest = $resultArray;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }

    static function GetUsers(){
      $link = openlink();
      $query = "SELECT * FROM users";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      }else {
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $resultArray = $result->fetch_all();
          $finalTest = $resultArray;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }

    static function GetClients(){
      $link = openlink();
      $l = 4;
      $query = "SELECT * FROM users WHERE access_level_id = ?";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      }else {
        mysqli_stmt_bind_param($stmt, "i", $l);
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $resultArray = $result->fetch_all();
          $finalTest = $resultArray;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }

    static function AddUser(
      $f_name,
      $l_name,
      $ll_name,
      $email,
      $access_level,
      $status,
      $phone,
      $joinDate,
      $clientNum,
      $hashedPW
    ){
      $link = openlink();
      $query = "INSERT INTO users (
        name,
        l_name,
        ll_name,
        phone,
        email,
        status,
        access_level_id,
        join_date,
        contract_id,
        password
      )
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      }else {
        mysqli_stmt_bind_param(
          $stmt,
          "sssssiisss",
          $f_name,
          $l_name,
          $ll_name,
          $phone,
          $email,
          $status,
          $access_level,
          $joinDate,
          $clientNum,
          $hashedPW
        );
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $finalTest = true;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }

    static function UpdateUser($id, $userInfo){
      $link = openlink();
      $query = "UPDATE users SET
        name = ?,
        l_name = ?,
        ll_name = ?,
        email = ?,
        access_level_id = ?,
        phone = ?,
        status = ?,
        join_date = ?,
        contract_id = ?,
        password = ?
        WHERE user_id = ? LIMIT 1";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      }else {
        mysqli_stmt_bind_param(
          $stmt,
          "ssssisisssi",
          $userInfo('name'),
          $userInfo('l_name'),
          $userInfo('ll_name'),
          $userInfo('email'),
          $userInfo('access_level_id'),
          $userInfo('phone'),
          $userInfo('status'),
          $userInfo('join_date'),
          $userInfo('contract_id'),
          $userInfo('password'),
          $id
        );
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $finalTest = true;
        } else {
          $finalTest = "false5";
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }

    static function UpdateUserPasswordByID($password, $id){
      $link = openlink();
      $query = "UPDATE users SET
        password = ?
        where user_id = ? LIMIT 1";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      } else {
        mysqli_stmt_bind_param(
          $stmt,
          "si",
          $password,
          $id
        );
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $finalTest = true;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }

    //---------------ACCESS LEVELS-----------------------------

    static function GetAccessLevels(){
      $link = openlink();
      $query = "SELECT * FROM access_levels";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      }else {
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $resultArray = $result->fetch_all();
          $finalTest = $resultArray;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }

    //---------------Follow Ups-----------------------------

    static function GetFUByUserID($id){
      $link = openlink();
      $query = "SELECT * FROM follow_up WHERE user_id = ? ORDER BY created_at DESC";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      }else {
        mysqli_stmt_bind_param($stmt, "i", $id);
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $resultArray = $result->fetch_all();
          $finalTest = $resultArray;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }

    static function AddFu($targetID, $senderID, $type, $message){
      $link = openlink();
      $date = date("Y-m-d H:i:s");
      $query = "INSERT INTO follow_up (user_id, created_by, created_at, type, message) VALUES (?, ?, ?, ?, ?)";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      }else {
        mysqli_stmt_bind_param($stmt, "iisis", $targetID, $senderID, $date, $type, $message);
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $finalTest = true;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }











    //-------REPURPUSING Pool

    //---------------USER-----------------------------



    static function QuickAddUser($email, $f_name, $l_name, $ll_names, $hashedPW){
      $link = openlink();
      $status = 1;
      $accessLevel = 8;
      $query = "INSERT INTO users (email, f_name, l_name, ll_name, password, status, access_level_id)
        VALUES (?, ?, ?, ?, ?, ?, ?)";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      }else {
        mysqli_stmt_bind_param(
          $stmt,
          "sssssii",
          $email,
          $f_name,
          $l_name,
          $ll_names,
          $hashedPW,
          $status,
          $accessLevel
        );
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $finalTest = true;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }




    static function GetUserByUsername($username){
      $link = openlink();
      $query = "SELECT * FROM users WHERE username = ? LIMIT 1";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      }else {
        mysqli_stmt_bind_param($stmt, "s", $username);
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $resultArray = $result->fetch_assoc();
          $finalTest = $resultArray;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }

    static function GetUsersByNames($string){
      $link = openlink();
      $string = "%".$string."%";
      $query = "SELECT * FROM users WHERE f_name LIKE ? OR l_name LIKE ? OR ll_name LIKE ?";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      }else {
        mysqli_stmt_bind_param($stmt, "sss", $string, $string, $string);
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $resultArray = $result->fetch_all();
          $finalTest = $resultArray;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }

    static function GetStudentsByGroupID($groupID){
      $link = openlink();
      $query = "SELECT * FROM users WHERE group_id = ? ORDER BY l_name DESC";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      }else {
        mysqli_stmt_bind_param($stmt, "i", $groupID);
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $resultArray = $result->fetch_all();
          $finalTest = $resultArray;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }

    static function GetStudentsBySchoolYearID($yearID){
      $link = openlink();
      $query = "SELECT * FROM users WHERE grado_id = ? ORDER BY l_name DESC";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      }else {
        mysqli_stmt_bind_param($stmt, "i", $yearID);
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $resultArray = $result->fetch_all();
          $finalTest = $resultArray;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }

    static function GetFamilyByChildID($userID){
      $link = openlink();
      $query = "SELECT * FROM family_student WHERE student_id = ?";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      }else {
        mysqli_stmt_bind_param($stmt, "i", $userID);
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $resultArray = $result->fetch_all();
          $finalTest = $resultArray;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }

    static function GetChildrenByFamilyID($userID){
      $link = openlink();
      $query = "SELECT * FROM family_student WHERE family_member_id = ?";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      }else {
        mysqli_stmt_bind_param($stmt, "i", $userID);
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $resultArray = $result->fetch_all();
          $finalTest = $resultArray;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }

    static function GetUserByIDArray($id){
      $link = openlink();
      $query = "SELECT * FROM users WHERE user_id = ? LIMIT 1";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      }else {
        mysqli_stmt_bind_param($stmt, "i", $id);
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $resultArray = $result->fetch_all();
          $finalTest = $resultArray;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }

    static function GetUsersByAccessLevel($accessLevel){
      $link = openlink();
      $query = "SELECT * FROM users WHERE access_id = ? ORDER BY l_name DESC";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      }else {
        mysqli_stmt_bind_param($stmt, "i", $accessLevel);
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $resultArray = $result->fetch_all();
          $finalTest = $resultArray;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }

    static function linkToStudentByTargetUserID($id, $studentID){
      $link = openlink();
      $query = "INSERT INTO family_student (student_id, family_member_id) VALUES (?, ?)";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      } else {
        mysqli_stmt_bind_param(
          $stmt,
          "ii",
          $studentID,
          $id
        );
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $finalTest = true;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }

    static function UnlinkStudent($id, $studentID){
      $link = openlink();
      $query = "DELETE FROM family_student WHERE student_id = ? AND family_member_id = ? LIMIT 1";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      } else {
        mysqli_stmt_bind_param(
          $stmt,
          "ii",
          $studentID,
          $id
        );
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $finalTest = true;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }

    static function AddStudentToGroup($groudID, $studentID){
      $link = openlink();
      $query = "UPDATE users SET
        group_id = ?
        where user_id = ? LIMIT 1";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      } else {
        mysqli_stmt_bind_param(
          $stmt,
          "ii",
          $groudID,
          $studentID
        );
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $finalTest = true;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }

    static function UpdateUserPhotoByID($photoLoc, $id){
      $link = openlink();
      $query = "UPDATE users SET
        profile_photo = ?
        where user_id = ? LIMIT 1";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      } else {
        mysqli_stmt_bind_param(
          $stmt,
          "si",
          $photoLoc,
          $id
        );
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $finalTest = true;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }

    static function UpdateUserStatusByID($id, $status){
      $link = openlink();
      if ($status) {
        $tempStatus = 1;
      } else {
        $tempStatus = 0;
      }

      $query = "UPDATE users SET
        status = ?
        where user_id  = ? LIMIT 1";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      } else {
        mysqli_stmt_bind_param(
          $stmt,
          "ii",
          $tempStatus,
          $id
        );
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $finalTest = true;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }

    //---------------SCHOOL GRADE YEARS-----------------------------

    static function AddSchoolYear($yearName){
      $link = openlink();
      $status = 1;
      $query = "INSERT INTO grados ( name, status) VALUES (?, ?)";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      }else {
        mysqli_stmt_bind_param($stmt, "si", $yearName, $status);
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $finalTest = true;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }

    static function GetSchoolYearGrades(){
      $link = openlink();
      $query = "SELECT * FROM grados";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      }else {
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $resultArray = $result->fetch_all();
          $finalTest = $resultArray;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }

    static function GetSchoolYearByID($id){
      $link = openlink();
      $query = "SELECT * FROM grados WHERE grados_id  = ? LIMIT 1";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      }else {
        mysqli_stmt_bind_param($stmt, "i", $id);
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $resultArray = $result->fetch_assoc();
          $finalTest = $resultArray;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }

    static function UpdateSchoolYear($id, $year){
      $link = openlink();
      $query = "UPDATE grados SET
        name = ?
        WHERE grados_id   = ? LIMIT 1";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      } else {
        mysqli_stmt_bind_param(
          $stmt,
          "si",
          $year('name'),
          $id
        );
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $finalTest = true;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }

    static function UpdateSchoolYearStatusByID($id, $status){
      $link = openlink();
      if ($status) {
        $tempStatus = 1;
      } else {
        $tempStatus = 0;
      }

      $query = "UPDATE grados SET
        status = ?
        where grados_id = ? LIMIT 1";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      } else {
        mysqli_stmt_bind_param(
          $stmt,
          "ii",
          $tempStatus,
          $id
        );
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $finalTest = true;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }

    //---------------ACCESS LEVELS-----------------------------


    static function AddAccessLevel($yearName){
      $link = openlink();
      $query = "INSERT INTO acess_levels (name) VALUES (?)";
      $stmt = mysqli_stmt_init($link);
      if (!mysqli_stmt_prepare($stmt, $query)) {
        //return false if there was an error
        return false;
      }else {
        mysqli_stmt_bind_param($stmt, "s", $yearName);
        if (mysqli_stmt_execute($stmt)) {
          $result = $stmt->get_result(); // get the mysqli result
          $finalTest = true;
        } else {
          $finalTest = false;
        }
      }
      closeLink($stmt, $link);
      return $finalTest;
    }
  }

  //open link
  include 'dbConnect.inc.php';

  //closing link
  function closeLink($stmt, $link){
    mysqli_stmt_close($stmt);
    mysqli_close($link);
  }
  //date("Y-m-d H:i:s")
?>

As you can see I repeat most of the code over and over, I think I could do one method for each CRUD and then somehow just pass the differences… any ideas??

multi classing – Does a PF2e spellcaster who takes multiclass dedications into other spellcasting classes, and related spellcasting feats, gain more spell slots?

Ezren is a level 10 evocation wizard, and hence would have spell slots of the following levels:

+-------------+-----------------+
| Spell level | Number of slots |
+-------------+-----------------+
|           1 |               4 |
|           2 |               4 |
|           3 |               4 |
|           4 |               4 |
|           5 |               4 |
+-------------+-----------------+

However, at level 2 Ezren took the Sorcerer multiclass dedication. At level 4 he took Basic Sorcerer Spellcasting, and Bloodline Breadth at level 8.

How many spell slots does Ezren have in a given day? Is it:

+-------------+-----------------+
| Spell level | Number of slots |
+-------------+-----------------+
|           1 |               6 |
|           2 |               6 |
|           3 |               6 |
|           4 |               4 |
|           5 |               4 |
+-------------+-----------------+

Because at level 8, spellcasting archetype feats grant an additional spell slot of first, second and third level, AND the bloodline breadth feat increases each of these by one?

Or do these sources of spell slots not stack for some reason? Coming from fifth edition, a wizard who multiclasses sorcerer still has the same number of spell slots as a pure wizard, so I’d like to clarify my understanding here.

The set of isomorphism classes of Z/nZ-equivariant line bundles over a 2 dimensional Z/nZ-CW complex

Suppose I wish to find the set of isomorphism classes of $mathbb{Z}/nmathbb{Z}$-equivariant line bundles over a 2-dimensional, compact $mathbb{Z}/nmathbb{Z}$-CW-complex $X$, i.e. $mathrm{Vect}^{1}_{mathbb{Z}/nmathbb{Z}}(X)$, I can write it using equivariant homotopy theory as

$mathrm{Vect}^{1}_{mathbb{Z}/nmathbb{Z}}(X)approx(X,B_{mathbb{Z}/nmathbb{Z}}GL_{1}(mathbb{C}))_{mathbb{Z}/nmathbb{Z}}$.

Nonequivariantly, $B_{mathbb{Z}/nmathbb{Z}}GL_{1}(mathbb{C})$ is $K(mathbb{Z},2)$ so the above would seem like a Bredon cohomology group $H^2_{mathbb{Z}/nmathbb{Z}}(X;M)$ with $M$ some Mackey functor and I could try to use the universal coefficients spectral sequence to attempt at computing it, however it seems like an awful lot of machinery for one of the simpler cases.

If the action is relatively nice, though it has fixed points, is there a simpler way of finding
$mathrm{Vect}^{1}_{mathbb{Z}/nmathbb{Z}}(X)$?

If not, which Mackey functor $M$ is the right one?

Thanks for your time

design – Why are Description classes useful in oop

“If an item in the inventory is sold or deleted, the stock count will be updated from the database” –

It’s not about that. This is not a generalized OOP recommendation, this is about the kinds of relationships that arise in certain domains.

If an item is sold out, you still can go to the database and query the price or details of that product. The table that stores product details, as well as the stock count is a description of a product. But sometimes it’s not enough to just store the count, sometimes you need extra data, perhaps better represented by a separate table or an object. Again, this whole discusion is not really related to OOP itself, it’s about domain modeling.

E.g., suppose you’re selling stuff online. You may want to keep generalized product descriptions & specs (something that people might search for) separate from data about the concrete items you have on stock (e.g., these might store info on whether the item is new or second-hand, if it’s damaged, a note about the item itself, etc.)

java – Como trabalhar com Classes que tenham outras Classes como atributo SpringBoot

Eae gente , essa é primeira vez que to programando pra web e to usando o spring boot pra isso , é um projeto da faculdade onde o FrontEnd vai ser feito em JS com React e o Back feito em JAVA com Spring . com o banco de dados postgres.
Eu fiquei com o Back end , e tudo ia bem até eu precisar trabalhar com classes compostas (classes que tem outras classes como atributo).
Tenho que fazer meio que uma lista de compra , uma Classe carrinho que tem como atributo um arrayList de compras , no qual compra tem como atributo um produto.

package com.api.springboot.model;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import org.hibernate.annotations.Cascade;
import org.springframework.data.annotation.CreatedDate;

import javax.persistence.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Entity
@Table(name = "carrinhos")
public class Carrinho implements Serializable {

    private static final long serialVersonUID = 1L;

    public Carrinho() {
        this.terminado = false;
    }


    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String nome;
    private boolean terminado;
    private float precoTotal;


    @OneToMany
            //(cascade = CascadeType.ALL, mappedBy = "carrinhos")
    @JoinColumn(name = "carrinho_id")
    private List<Compra> compras = new ArrayList<>();

    @ManyToOne
    private Comprador comprador;

    @CreatedDate
    private Date criadoEm = new Date();

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public boolean isTerminado() {
        return terminado;
    }

    public void setTerminado(boolean terminado) {
        this.terminado = terminado;
    }

    public float getPrecoTotal() {
        return precoTotal;
    }

    public void setPrecoTotal(float precoTotal) {
        this.precoTotal = precoTotal;
    }

    public void setCriadoEm(Date criadoEm) {
        this.criadoEm = criadoEm;
    }

    public List<Compra> getCompras() {
        return compras;
    }

    public void setCompras(List<Compra> compras) {
        this.compras = compras;
    }

    public void adicionarCompra(Compra compra){
        this.compras.add(compra);
    }

    public Date getCriadoEm() {
        return criadoEm;
    }

    public Comprador getComprador() {
        return comprador;
    }

    public void setComprador(Comprador comprador) {
        this.comprador = comprador;
    }

    public void add(Compra compra){
        compras.add(compra);
    }

    @Override
    public String toString() {
        return "Carrinho{" +
                "id=" + id +
                "n, nome='" + nome + ''' +
                "n, terminado=" + terminado +
                "n, precoTotal=" + precoTotal +
                "n, compras=" + compras +
                "n, comprador=" + comprador +
                "n, criadoEm=" + criadoEm +
                '}';
    }


}


package com.api.springboot.model;
import org.hibernate.annotations.ManyToAny;
import org.springframework.data.annotation.CreatedDate;

import javax.persistence.*;
import java.io.Serializable;
import java.time.*;
import java.util.Date;

@Entity
@Table(name = "compras")
public class Compra implements Serializable {


    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "produto_id")
    private Produto produto = new Produto();

    private int quantidade;
    private float precoTotal;

    @ManyToOne
    @JoinColumn(name = "carrinho_id")
    private Carrinho carrinho;

    @OneToOne
    private Promocao promocao;

    @CreatedDate
    private Date criadoEm = new Date();

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public Produto getProduto() {
        return produto;
    }

    public void setProduto(Produto produto) {
        this.produto = produto;
    }

    public int getQuantidade() {
        return quantidade;
    }

    public void setQuantidade(int quantidade) {
        this.quantidade = quantidade;
    }

    public float getPrecoTotal() {
        return precoTotal;
    }

    public void setPrecoTotal(float precoTotal) {
        this.precoTotal = precoTotal;
    }

    public Date getCriadoEm() {
        return criadoEm;
    }

    public Promocao getPromocao() {
        return promocao;
    }

    public void setPromocao(Promocao promocao) {
        this.promocao = promocao;
    }

    public void setCriadoEm(Date criadoEm) {
        this.criadoEm = criadoEm;
    }

    public Carrinho getCarrinho() {
        return carrinho;
    }

    public void setCarrinho(Carrinho carrinho) {
        this.carrinho = carrinho;
    }

    @Override
    public String toString() {
        return "Compra{" +
                "id=" + id +
                ", produto=" + produto +
                ", quantidade=" + quantidade +
                ", precoTotal=" + precoTotal +
                ", carrinho=" + carrinho +
                ", promocao=" + promocao +
                ", criadoEm=" + criadoEm +
                '}';
    }
}


´´´
´´´
package com.api.springboot.model;

import org.springframework.data.annotation.CreatedDate;

import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.Date;

@Entity
@Table(name = "produtos")
public class Produto {
    private static final long serialVersonUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String nome;
    private float preco;
    private float peso;
    private boolean tipo;

    @ManyToOne
    private Categoria categoria;

    @CreatedDate
    private Date criadoEm = new Date();

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getNome() { return nome; }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public float getPreco() {
        return preco;
    }

    public void setPreco(float preco) {
        this.preco = preco;
    }

    public float getPeso() {
        return peso;
    }

    public void setPeso(float peso) {
        this.peso = peso;
    }

    public boolean isTipo() {
        return tipo;
    }

    public void setTipo(boolean tipo) {
        this.tipo = tipo;
    }

    public Date getCriadoEm() {
        return criadoEm;
    }

    public Categoria getCategoria() {
        return categoria;
    }

    public void setCategoria(Categoria categoria) {
        this.categoria = categoria;
    }

    @Override
    public String toString() {
        return "Produto{" +
                "id=" + id +
                ", nome='" + nome + ''' +
                ", preco=" + preco +
                ", peso=" + peso +
                ", tipo=" + tipo +
                ", categoria=" + categoria +
                ", criadoEm=" + criadoEm +
                '}';
    }
}

Essas são as 3 classes principais vou colocar somente o controlador de carrinho pois se me ajudarem com ele acredito que consigo usar a lógica para os outros.

package com.api.springboot.controllers;

import com.api.springboot.model.Carrinho;
import com.api.springboot.model.Compra;
import com.api.springboot.repository.CarrinhoRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping(value = "/api")
public class CarrinhoController {

    @Autowired
    CarrinhoRepository carrinhoRepository;

    @GetMapping("/carrinhos")
    public List<Carrinho> listarCompras(){
        return carrinhoRepository.findAll();
    }

    @GetMapping("/carrinho/{id}")
    public Carrinho carrinhoById(@PathVariable(value = "id") long  id){
        return carrinhoRepository.findById(id);
    }

    @PostMapping("/carrinho")
    public Carrinho salvarCarrinho(@RequestBody Carrinho carrinho){
        return carrinhoRepository.save(carrinho);
    }

    @DeleteMapping("/carrinho")
    public void deletaCarrinho(@RequestBody Carrinho carrinho){
        carrinhoRepository.delete(carrinho);
    }

    @DeleteMapping("/carrinho/{id}")
    public void deletetById(@PathVariable(value = "id")long id){
        carrinhoRepository.deleteById(id);
    }

    @PutMapping("/carrinho/put")
    public Carrinho atualizarCarrinho(@RequestBody Carrinho carrinho){
        return carrinhoRepository.save(carrinho);
    }


    @PostMapping("/teste/{id}")
    public void add(@PathVariable(value = "id") long id , @RequestBody Compra x){
        Carrinho instancia = carrinhoRepository.findById(id);
        System.out.println(instancia);
        System.out.println(x);
//        instancia.add();
//        carrinhoRepository.save(instancia);
//        System.out.println("Rodou o dream do dream quero");
//        System.out.println(instancia);
    }

}

A minha dúvida é , como que eu adiciono uma compra em carrinho . Eu tentei usar a compra x vindo do front como parâmetro e adicionar ela , só que ela vem nula.
inserir a descrição da imagem aqui
Aí uma foto de como chega , eu nunca usei injeção de dependências e todos os tutorias os professores só usam classes com atributos de tipo int,String,boolean …

gn.general topology – Isotopy Classes of Non-Connected Planar Sets

I was just looking through some of my old questions on StackExchange and noticed that this one went totally unresolved. I still think it’d be useful as a lemma for plane topology if it were true, and would be curious to see a counterexample if not.

Suppose we are given two pairs $(U, V)$ and $(Y, Z)$ of connected, simply connected, bounded, open sets in the plane, where $U cap V = Y cap Z = varnothing$. However, their boundaries may intersect. Assume their closures are also simply connected. Let $A = U cup V$ and $B = Y cup Z$. Suppose we also know the following, where ‘$simeq$‘ refers to planar isotopy:

  1. $U simeq Y$

  2. $V simeq Z$

  3. $bar{U} cap bar{V} simeq bar{Y} cap bar{Z}$

Then this is not enough to imply that $A simeq B$, due to an example at the bottom of this post.

So I’m wondering, what are some of the simplest conditions we can add on to those three above to ensure that $A simeq B$?

  1. Is it enough that $bar{A}$ is homeomorphic to $bar{B}$?

  2. Alternatively, assume $bar{U} setminus bar{V}$ is homeomorphic to $bar{Y} setminus bar{Z}$. Would assuming this, as well as its obverse for $bar{V} setminus bar{U}$ and $bar{Z} setminus bar{Y}$, be sufficient?

Counterexample, as promised: Let $U = Y$ be a ‘thickened open topologist’s sine curve’, i.e. a shrinking tubular neighborhood of the standard topologist’s sine curve with limit arc being $(-1, 1)$ on the $y$-axis (though not itself containing this arc, just the ‘wiggly part’ on $(0, pi)$). Let $V$ be the reflection of $U$ across the $y$-axis, and let $Z$ be the same as $V$ except scaled by $frac{1}{2}$ vertically. So in other words $Z$ is just a vertically-squished topologist’s sine curve coming from the other direction. Then clearly $U, V, Y, Z$ satisfy all of the above conditions (condition 3 is satisfied since each is just an arc, albeit of different lengths) but $A notsimeq B$.

Obviously, this problem could be generalized in all sorts of ways, though Lakes of Wada phenomena would be a complication if you start increasing the number of components in $A$ and $B$.

nt.number theory – Norm forms, slicing, and ideal classes

Let $K$ be a number field, which we may suppose satisfies $n = (K : mathbb{Q}) geq 3$. Let $mathcal{O}_K$ be the ring of integers of $K$, and let ${omega_1, cdots, omega_{n}}$ be a basis of $mathcal{O}_K$. Define the norm form of $K$ to be the homogeneous polynomial defined by

$displaystyle N_{K/mathbb{Q}}(mathbf{x}) = prod_{sigma : K hookrightarrow mathbb{C}} left(sigma(omega_1) x_1 + cdots + sigma(omega_n) x_nright),$

where the product runs over embeddings $sigma: K hookrightarrow mathbb{C}$.

We can extend this definition of norm form to any order $mathcal{O}$ contained in $mathcal{O}_K$, by replacing the basis ${omega_1, cdots, omega_n}$ with a basis for $mathcal{O}$.

Now suppose that $mathcal{O}$ is an order, with basis ${nu_1, cdots, nu_n}$, say, and let $N_{mathcal{O}}(mathbf{x})$ be the corresponding norm form. Let us take an element $A in text{GL}_n(mathbb{Z})$, and consider $G : = N_{mathcal{O}}(A mathbf{x})$. Now restrict $N_{mathcal{O}}, G$ to the 2-dimensional space defined by $x_3 = cdots = x_n = 0$, to obtain binary $n$-ic forms $f(x_1, x_2),g(x_1, x_2)$ say.

What can we say about $f,g$ in general? In particular, are their discriminants connected in any way? What about the rings/ideal classes they represent?

design – “Assign” Role Association between two classes

If there is Class A and Class B and there is an association that B can be assigned to A.And the multiplicity is 1:M or M:1 from A to B.Example:

1.Room has Collection of Keys, and Key can can assigned to Room.

2.Match has a Referee, and Referee can be assigned to Collection of Matches.

I want to know, what would be correct place to put an assign Method?

In example 1, Room should have an assign(RoomKey) Method or RoomKey should have assingToRoom(Room) method?Are both ways correct?

c# – How to deal with references to shared manager classes

I am using C# with MonoGame, although this is relevant for any object-oriented programming language

Static classes should be reserved for stateless utility classes (for example System.Math) and they should generally be avoided along with singletons for manager-like classes. The reason for this is it prevents object-oriented strategies and may be under the false pretense that there is only one instance required at all times.

To solve these issues you could have instances like AudioManager, EffectManager, Time, etc. in a single global static object. But this does not solve another issue which is you do not control who has access to these instances. So instead pass in these instances from the top down through constructors to classes who need to access certain things.

In my game I have an entity component system. Character derives from Actor which derives from Component which is contained within an Entity. When a Character gets hit I want time to stop briefly (Time instance), the camera should shake (Camera instance), he should flash white (Effects instance), Damage text should be spawned (FloatingText instance) and a sound effect should be emitted (AudioManager instance).

This is just one example and child classes may need more things or pass in different parameters to these instances. Additionally, anyone higher up the hierarchy will need more instance references if they need to pass it down to someone who is lower down.

Q: “What is the problem in that?” A: “It is cumbersome and I am modifying an entire hierarchy when I want to change something one place”

If I realize a component needs a reference to another instance I need to modify the code throughout the entire hierarchy. A solution is to make the global static object itself a non-static instance and pass down the whole thing to all components (but I might only pass down a certain instance to other parts of the game).

“Maybe you just have a coupling problem? Character should not be the one to stop time, shake camera, etc.”

Okay, who should then? I could use an OnHit event in Character and let AudioManager for example hook up to that for all characters and play a sound effect with different parameters depending on the type of Character. But now I need to make a switch statement on type inside AudioManager, not very object-oriented. Instead, I could have one request manager instance to all of these things that takes in a parameter list as well. But what is the difference between this and a shared object instance? Anyone with a reference to request manager can make any request it’s just a bit more indirect.

Passing in a container to all shared instances in the constructor of e.g. Component seems like the best compromise. What do you think?

at.algebraic topology – Chern classes of a mapping torus vector bundle in terms of the construction data

Let $pi:Eto X$ be a complex vector bundle*, and $f:Eto E$ an bundle isomorphism.
Consider the mapping torus
$$E(f) := frac{Etimes (0,1)}{E times {0}sim_f E times {1}}$$
where the identification is the obvious one: $(x,0)sim_f (f(x),1)$.

$E(f)$ is also a complex vector bundle over $ Xtimes mathbb{S}^1$, the fibration is given by the map $(x,t)in E(f) mapsto (pi(x), t)in Xtimes mathbb{S}^1$.
The rank of $Eto X$ and $E(f)to Xtimes mathbb{S}^1$ is the same.

Problem:

Express the Chern classes of $E(f)$ in terms of the Chern classes of $E$ and the automorphism $f$.

This naively should be possible since all the data used to build $E(f)$ is in $E$ and $f$.
Of course if $f=id$ then the characteristic classes are the same. Probably also the case when $f$ is of finite order may be carried out.

$E(f)$ depends only on the isotopy class of $f$ therefore, the characteristic classes of $E(f)$ should tell us (something) about whether $f$ lies in the identity component of the gauge group $Aut(E)$.
If this is correct however the problem might not be that easy, since I believe that $pi_0 Aut(E)$ for generic $X$ (any dimension, any rank of $E$) is not known. But maybe I am missing something, please correct me if I’m wrong.

Since characteristic classes are related to sections, it is natural try to understand them.
If we have a section $u: Xto E$, we can construct a section $mu:Xtimes mathbb{S}^1to E(f)$ by putting $mu(x,t) = (u(x)(1-t) + tf (x)(u(x)),t)$.
Notice $mu(x,t)$ is zero when $u(x)$ meets a $lambda$-eigenspace of $f(x)in Aut(E|_x)$ with $lambda<0$ (or when u(x) is zero)).
However eigenspaces of $f$ do not define a subbundle (dimension can jump). I expect these subspaces to show up in a possible formula (if there is one).

Hopefully experts in homotopy theory will tell me more.

*Everything is smooth/manifold.