Our experience with Javafx at a Hackathon

0 likes

What hackathon did we participate

We participated in this hackathon called the OpenHack. It was our first hackathon and a hackathon of over 700 participants. It was certainly a fun experience, and we went on attending over seven other hackathon events. This Hackathon was generally well organized - it had a dozen admins organizing the chat and the event. This also gave us inspiration on whether we want to host our own online hackathon.

Why Java?

There were mainly two reasons behind why we wanted to use Java at this hackathon:
  1. Our school's design class required us to make a Java application, and so we decided to just carry on with the language.
  2. We also wanted to use this chance to practice Java since we wanted to take the AP CS exam.

What is the software

Our project was composed of two things:
  1. An advanced group generator that generates groups based on discriminators such as nationality, gender, hobby and more.
  2. In a typical group generator, the only decider for the groups is randomness. However, in an international school, randomness sometimes isn't the ideal decider for group activities, assignments, and school tasks. Our group generator can let the teacher decide, for instance, whether to mix up all the people by nationality or to mix up all the people who agree and disagree with a topic.
  3. An online education facilitator that generates google meet links or zoom links along with the groups.
  4. Secondly, we noticed during the Covid-19 pandemic that our secondary teachers needed a better way of creating and sharing Google Meet links with their students. For instance, many times, they wanted to schedule a Google Meet in advance, but the links expired, and they were not able to do this. Other times, they simply wanted to create breakout Meets but had to ask one of the students to create meet links for them. However, our software combines this with group generation, by automatically embedding google meet/zoom links inside emails sent to each of the groups. This makes group work and activities easier for online learning, hence improving and creating new ways in which teachers can structure their online classes.

How we made it

Our software can be separated into two parts that are parallel to the two main functions of the group generator: the group generating algorithm and google meet/zoom link extraction.

Group generating algorithm:

It was a straightforward fact that we were dealing with the properties of each student, which means we would first create a student class and organize the students into objects.
package sample;

public class Student {
    private String name;
    private String nationality;
    private String homeRoom;
    private String gender;
    private String email;


    public Student(String name, String gender, String nationality, String homeRoom, String email){

        this.name = name;
        this.email = email;
        this.nationality = nationality;
        this.homeRoom = homeRoom;
        this.gender = gender;

    }

    public String getName() {
        return name;
    }

    public String getEmail(){
        return email;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getNationality() {
        return nationality;
    }

    public void setNationality(String nationality) {
        this.nationality = nationality;
    }

    public String getHomeRoom() {
        return homeRoom;
    }

    public void setHomeRoom(String homeRoom) {
        this.homeRoom = homeRoom;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }


    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", nationality='" + nationality + '\'' +
                ", homeRoom='" + homeRoom + '\'' +
                ", gender='" + gender + '\'' +
                '}';
    }
}
The next goal was to evenly distribute the students based on two user inputs: number of groups and the discriminator the grouping process would be based on. To execute this grouping method in a very organized and structured manner, we decided to format it with List<List<Student>>. Using the List Interface, we wrapped the student objects with a list, representing each group, and we wrapped that with another list, representing all the groups. List<> is a single group; List<List<Student>>is a group of groups. Then, we created a function that sorts the groups. In our sorting class, as we were reading the student’s information from a CSV file, we set up a constructor that syncs the file path to a local variable. After that, we implemented the method of distributing the groups - this method was suggested by an answer to my StackOverflow post, a very succinct and effective method. Below is a snippet of our function:
        public List> sort(String type, int groupNum) {
        this.groupNum = groupNum;

        ReadFile p = new ReadFile(filePath);
        List people = new ArrayList<>();
        for (int i = 1; i < new ReadFile(filePath).readLine(); i ++) {
            people.add(
                    new Student(
                            p.read(i, 0),
                            p.read(i, 1),
                            p.read(i, 2),
                            p.read(i, 3),
                            p.read(i, 4)
                    )
                    //(name, gender, nationality, homeroom, email)
            );
        }

        Collections.shuffle(people);//randomize the list of people

        Function discriminator;
        //check the type of sorting the user wants
        switch(type) {
            case "homeroom":
                discriminator = Student::getHomeRoom;
                break;
            case "gender":
                discriminator = Student::getGender;
                break;
            case "nationality":
                discriminator = Student::getNationality;
                break;
            case "random":
                discriminator = Student::getName;
                break;
            default:
                discriminator = Student::getName;
                System.out.println("ERROR");
        }

        AtomicInteger index = new AtomicInteger();
        List> groups = new ArrayList<>(people.stream()
                .sorted(Comparator.comparing(discriminator))
                .collect(Collectors.groupingBy(e -> index.getAndIncrement() % groupNum))
                .values());
        return groups;//returns List>
    }

This was especially novel to us due to its usage of AtomicIntegers and a unique sorting method. Even though I don't fully understand how to manipulate these elements, using some high-level Java techniques does make it very efficient.

Link Extraction:

For the second part of our code, our goal was to make the code to extract Google Meet and Zoom links automatically. We decided to use Selenium. At first, we thought Selenium was a very esoteric thing that was extremely hard to use. However, it is pretty straightforward. First of all, we downloaded a Chrome driver and pointed it in our code.
    public void setBrowserConfigure(){
        System.setProperty("webdriver.chrome.driver", driverr);
    }
We created separate functions for Zoom and Google Meet. Below is the code for Google Meet:
 public String[] generateGoogleMeetLinks(int numLinks){
        //System.setProperty("webdriver.chrome.driver", driverr);//put your driver exe here

        final String baseUrl = "https://meet.google.com/new";
        ChromeOptions options = new ChromeOptions();

        WebDriver driver = new ChromeDriver(options);
//        driver.manage().window().setPosition(new Point(-2000, 0));//put it to the left
        meetLinksList = new String[numLinks];
        for(int i = 0; i < numLinks; i++){
            try {
                driver.get(baseUrl);

                if(i == 0) { //for the first link, we need to log into google
                    new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(By.xpath("//input[@id='identifierId']"))).sendKeys(teacherAddress);
                    driver.findElement(By.id("identifierNext")).click();
                    new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(By.xpath("//input[@name='password']"))).sendKeys(teacherPassword);
                    driver.findElement(By.id("passwordNext")).click();
                }
                Thread.sleep(1000);
                new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@id=\"yDmH0d\"]/div[3]/div/div[2]/span")));
                driver.findElement(By.xpath("//*[@id=\"yDmH0d\"]/div[3]/div/div[2]/span")).click();//clicking in the middle of the page
                Thread.sleep(1000);
                new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@id=\"yDmH0d\"]/div[3]/div/div[2]/div[3]/div/span/span")));
                driver.findElement(By.xpath("//*[@id=\"yDmH0d\"]/div[3]/div/div[2]/div[3]/div/span/span")).click();//clicks dismiss
                //new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(By.xpath("/html/body")));


                Thread.sleep(1000);
                new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@id=\"yDmH0d\"]/c-wiz/div/div/div[4]/div[3]/div/div[2]/div/div[2]/div/div[1]/div[1]/div[2]/div/div[1]")));
                link = driver.findElement(By.xpath("//*[@id=\"yDmH0d\"]/c-wiz/div/div/div[4]/div[3]/div/div[2]/div/div[2]/div/div[1]/div[1]/div[2]/div/div[1]")).getText();
                meetLinksList[i] = link;//filling the list

            }catch(InterruptedException e){
                e.printStackTrace();
            }catch(TimeoutException e){
                System.out.println("Time out!");
                e.printStackTrace();
            }
        }
        driver.close();
        return meetLinksList;
    }
In the code, we have a for-loop, which generates meet links for the number of the group the user requested. Then, to be able to deal with the browser, as to extract specific elements from the web page, we had to utilize two Selenium elements: WebDriverWait() and findElement(). WebDriverWait() waits until the requested element is loaded through calling another function called until() right behind it. findElement() finds elements - in our code we used XPath, but there are a number of other options to specify the elements on the website. For this specific process, it logs into the Google account, directs to the Google Meet page, and finally copies the meet link. The link then goes through our Email functions and gets sent off to the groups. This took us a long time to calibrate. Check out our competition page here.

Challenges

How to use it

  1. Choose the classroom csv/excel file that you would like the groups to be from(you can also choose past groups). Then, type the desired number of groups.
  2. Select the group customization.
  3. Type the your google account or your zoom account. Then, select whether you would like to generate zoom or google meet links - you can also choose not to generate links.
  4. Type any announcement you would like to be sent along with the links to each individual groups
  5. Click Generate.
  6. Check out our source code here


Leave a Comment
/200 Characters