drewreed2005 / dre2.0

dre2.0
Apache License 2.0
0 stars 0 forks source link

Drew Reed, Period 1 - 2015 FRQ Project Connections and Overall Reflection #5

Open drewreed2005 opened 6 months ago

drewreed2005 commented 6 months ago

Project Connections

"Show how FRQs or principles of FRQs are incorporated into to your final project."

In the blogs linked at each header and on my submission comment table, I go over my answers to the questions and what I took away from each on a conceptual level. In this issue, I'll discuss how the concepts in these questions have been/could be implemented in my group's final project, Nighthawk Resources.

Question 1: 2D Arrays

This question primarily focused on iterating through both one-dimensional and two-dimensional arrays and checking for duplicates in array sums to determine if a 2D array is "diverse". While this exact sort of functionality doesn't currently have a place in our project, with each new user in our backend, certain checks are made to ensure that there are no duplicates. These users are collected in an SQL database. See the contents of the Person.java file below.

// automatic unique identifier for Person record
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

// email, password, roles are key attributes to login and authentication
@NotEmpty
@Size(min=5)
@Column(unique=true)
@Email
private String email;

The unique=true variable declaration tells the database that user objects cannot have the same email as each other. When a new user is created, if their email is determined to match an existing user, an error will be flagged and the user will not be created. This ensures that multiple accounts to not exist for a single user's credentials, which also helps to certify that a user is who they claim to be based on their identity.

This doesn't touch on arrays or iteration, however, since this is a check that's built into the JPA repository based on the tags provided, though all users stored in the database are almost certainly iterated through to find potential duplicates with the creation of a new user. Collections like arrays are, however, used to store objects with relationships to each other in our project. The most can be found in the ClassPeriod object:

// leaders in the class can control it; not "teachers" because it could be clubs
@ManyToMany(fetch = EAGER)
private Collection<Person> leaders = new ArrayList<>();

// students in the class have fewer permissions
@ManyToMany(fetch = EAGER)
private Collection<Person> students = new ArrayList<>();

@ManyToMany(fetch = EAGER)
private Collection<Assignment> assignments = new ArrayList<>();

If we wanted to just prevent duplicates, we could change the Collection objects from ArrayLists to Sets, but that would fail to preserve order. It might be helpful to preserve creation order, so we could also use a LinkedHashSet, which does preserve order:

// leaders in the class can control it; not "teachers" because it could be clubs
@ManyToMany(fetch = EAGER)
private Collection<Person> leaders = new LinkedHashSet<>();
    // etc.

There aren't any 2D arrays currently used in our project, but arrays as a whole and their relationships with each other and iteration were the main focus of the problem. This page shows the complicated JSON data (which sends multiple arrays full of object data) being iterated through and displayed in a styled fashion on our frontend. In general, iteration is very common in our frontend, though that's JavaScript, not Java.

Overall, arrays and collections as a whole are a crucial thing to consider for any code project that stores multiple pieces of data at once (which is the majority of all code projects).

Question 2: Classes

This question focused on making a POJO with a constructor and a method used alongside the object's attributes to make a word guessing game similar to Wordle. While there's obviously no Nighthawk Resources Official Wordle Minigame (...yet?), there are still takeaways here. Primarily, this question asks us to make a POJO. In our project, POJOs like our SQL model objects are crucial to the functionality of our program. Lombok tags are used to create a no-argument constructor. The code below is from the Assignment model file.

@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Convert(attributeName ="assignment", converter = JsonType.class)
public class Assignment {
    // automatic unique identifier for Assignment record
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @NonNull
    @Size(min = 2, max = 30, message = "Name (2 to 50 chars)")
    private String name;

    //date the assignment is created
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date dateCreated;

    // the date the assignment is due
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date dateDue;

    @NonNull
    @Size(min=2, max=5000, message = "Content (2 to 5000 chars)")
    private String content;

    // Constructor used when building object from an API
    public Assignment(String name, Date dateCreated, Date dateDue, String content) {
        this.name = name;
        this.dateCreated = dateCreated;
        this.dateDue = dateDue;
        this.content = content;
    }

The Assignment JPA Repository object uses the following methods, similar to the sorts of calls that are made when comparing the guess and the actual word in the problem, to interact with the attributes of the larger database of Assignment POJOs.

public interface AssignmentJpaRepository extends JpaRepository<Assignment, Long> {

    Assignment findById(long id);

    List<Assignment> findByName(String name);

    // etc.

    List<Assignment> findByDateDue(Date dateDue);
}

The constructor we created for Assignment is used in the POST method in AssignmentApiController, shown below. Interestingly, the AssignmentRequest object used to outline the request body also uses a constructor that is utilized implicitly by the JPA method, and getters are used when calling the argument constructor for Assignment below.

@PostMapping("/post")
public ResponseEntity<Object> postAssignment(@RequestBody AssignmentRequest request) {
   for (String className : request.getClassNames()) {
        if (classService.getByName(className) == null) {
            return new ResponseEntity<>("One or more classes was invalid", HttpStatus.BAD_REQUEST);
        }
    }
    // A assignment object WITHOUT ID will create a new record with default roles as student
    Assignment assignment = new Assignment(request.getName(), request.getDateCreated(), request.getDateDue(), request.getContent());
    assignmentDetailsService.save(assignment);

Since there isn't much of a connection to the context of this problem, the most important connections to be drawn are these broader and, ultimately, more important ones regarding the connections between POJOs and associated methods.

Question 3: Arrays/ArrayLists

This problem has multiple different identifiable areas of focus, but among the four questions, it is most similar to the first question. Since I already went over how our project accounts for duplicate data and handles iterative search processes, I wanted to focus more on the precise way that this prompt asks to handle data.

The method getValueAt(int row, int col) seen in the problem has similar functionality to the more specific data search methods found in our JPA repositories. For example, without going into interfaces (that's the focus of the next question), here are some methods of the PersonJpaRepository used to search for users in the database:

Person findByEmail(String email);

Person findByUsn(String usn);

// JPA query, findBy does JPA magic with "Name", "Containing", "Or", "Email", "IgnoreCase"
List<Person> findByNameContainingIgnoreCaseOrEmailContainingIgnoreCase(String name, String email);

Person findByEmailAndPassword(String email, String password);

The last two are especially pertinent, as they require two different matching pieces of data. The final of these is used for sign-in in our project, so it's especially important.

Raymond, a member of our group, also brought up how the JSON we use for storing a class's seating chart can be compared to 2D arrays. Unlike this problem, which represents a 2D structure implicitly with its row-column value representation, the seating chart can potentially be represented by rows (tables) and columns (student positions in those tables). We decided to represent the tables in the following JSON structure so that the position of each student at each table is defined at a specific table index. This explicit numerical representation might make it easier for teachers to specify at which position of a table a student is intended to sit, if this matters. The JSON below is taken from a sample of the formatting of a request to be sent from the frontend that will modify the seating chart of a specified class, provided the proper login credentials.

{
    "chart": {
        "1": {
            "1": "John",
            "2": "Alice"
        },
        "2": {
            "1": "Bob",
            "2": "Eve"
        }
    },
  // etc.
}

Question 4: Methods and Control Structures

Despite my initial overall lack of knowledge about interfaces and their intended use, I have interacted with them quite a lot before with the JPA repository files. The following, for example, is the interface ClassPeriodJpaRepository that extends the base JpaRepository, specifying ClassPeriod for the first argument (the entity type to be persisted) and Long (the data type of the id) for the second argument (the entity's primary key).

public interface ClassPeriodJpaRepository extends JpaRepository<ClassPeriod, Long> {
    ClassPeriod findByName(String name);

    List<ClassPeriod> findAllByOrderByNameAsc();

    // JPA query, findBy does JPA magic with "Name", "Containing", "Or", "Email", "IgnoreCase"
    List<ClassPeriod> findByNameContainingIgnoreCase(String name);

    List<ClassPeriod> findByLeadersContaining(Person leader);
    List<ClassPeriod> findByStudentsContaining(Person student);
}

Extending the JpaRepository interface allows my custom ClassPeriodJpaRepository interface to inherit CRUD methods like save (which acts as both create and update) and non-CRUD interaction methods like findById and existsById.

My custom methods listed below are named within the conventions of the Spring repository, and so, by specifying them, these new queries can be used to interact with the ClassPeriod database.

Interface implements can also be seen in our DetailsService objects.

@Service
@Transactional
public class PersonDetailsService implements UserDetailsService { 
    // methods below

This UserDetailsService implement provides means of interacting with user data from the database in the service class. The class overwrites the following method outlined in the UserDetailsService, specifying how to retrieve user data based on their username (email, actually):

    /* UserDetailsService Overrides and maps Person & Roles POJO into Spring Security */
    @Override
    public org.springframework.security.core.userdetails.UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        Person person = personJpaRepository.findByEmail(email); // setting variable user equal to the method finding the username in the database
        if(person==null) {
            throw new UsernameNotFoundException("User not found with username: " + email);
        }
        Collection<SimpleGrantedAuthority> authorities = new ArrayList<>();
        person.getRoles().forEach(role -> { //loop through roles
            authorities.add(new SimpleGrantedAuthority(role.getName())); //create a SimpleGrantedAuthority by passed in role, adding it all to the authorities list, list of roles gets past in for spring security
        });
        // train spring security to User and Authorities
        return new org.springframework.security.core.userdetails.User(person.getEmail(), person.getPassword(), authorities);
    }

As it turns out, although they've been removed from the AP curriculum, interfaces are very useful tools in our PBL environment, and, while some might not realize it, they are an extremely crucial part of our Spring Portfolio backend's functionality. By properly understanding it, we drastically increase our ability to manipulate the backend to our advantage, especially when it comes to interactions with database data and receiving data from outside sources.

Overall Reflection

I provided specific problem-based reflections in my blog here, but here are some overall grows and glows I wanted to provide about my performance.

Glows

Grows

See my overall takeaways and notes for question 1, question 2, question 3 and question 4 by clicking these hyperlinks.

Peer Grades

Here are my grades from my peer review with Alex Lu on Monday.

Portion Calculation Total (out of 3.6)
FRQs (with 1.125 multiplier) (1.1250.9) (0.97+1.0+0.95+0.95) 3.918/3.6
PBL Connections (no 1.125 multiplier) 0.9 * (0.93+1.0+0.95+1.0) 3.49/3.6
YLu-1258 commented 6 months ago
Cross Over Grading for FRQ Title Description Score
FRQ 1 - Compared solution to official solution from collegeboard, both solutions would provide the same answer and operates with the same logic.
- Provided some really good reflection on the issue, commenting throughout.
0.97/1.0
FRQ 2 - Solution works as intended when compared to official solution. No additional score penalties were assigned.
- Provided great documentation on the problem throughout, justified use of substring method over charAt(). I didn't even consider that this was a concern that we needed to address
- Provided additional code to finish the Wordle game
1.0/1.0
FRQ 3 - Solution is mostly working but an alternative is provided towards the end that works properly.
- Overall notes and reminders provided a good reflection of personal issues that could be addressed.
- Created a very intuitive and ingenious method of iterating by reverse so that the index is always kept accurate even if a specific element is removed. Good algorithmic programming.
- Very good engineering, constant thought throughout.
0.95/1.0
FRQ 4 - Solution is consistent with what the College Board expects.
- Reflection was good and made connection to PBL.
- Code comments were evident throughout the code, demonstrates high levels of thought.
0.95/1.0
Total (1.125*0.9)*(0.97+1.0+0.95+0.95) = 3.918/3.6
YLu-1258 commented 6 months ago
Cross Over Grading for PBL Title Description Score
FRQ 1 - No direct connection to any 2D implementation in project but provided other instances where similar logic was used
- valuable skill to connect Java techniques to other tech we work with. Still, the concept of 2D or nested arrays have broad implications and uses in programming, so I'd consider parts of the backend where you could potentially optimize or improve performance through a 2D array.
0.93/1.0
FRQ 2 - Provided a lot of instances where classes and POJOs were used effectively in the project.
- Demonstrated how the concept could be applied to the project and contribute to the application's overall functionality. The student shows that they can see far beyond just the main topic of the problem, which is good.
- Inspired me to adopt something similar in my backend.
1.0/1.0
FRQ 3 - Went beyond the expected connection, talked about how specific array operations and methods from the original FRQ parallels other aspects of the code to contribute to working, functional programming 0.95/1.0
FRQ 4 - Good explanation of a piece of technology that the student was initially unfamiliar with.
- Great demonstration of how an interface was used in the PBL. I also learned something new about how interfaces could be applied to our project for better code organization and implementation
1.0/1.0
Total 0.9*(0.93+1.0+0.95+1.0) = 3.49/3.6