# Project export: UCSC Building Activity Tracker

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: CruzHacks 2024
- Tagline: Easy Peasy, Check if it's busy.
- Devpost: https://devpost.com/software/ucsc-building-activity-tracker
- GitHub: https://github.com/achang93/UCSC_Location_Busy_Tracker.git
- Team: 4 GitHub contributor(s) — Albert Chang (36 commits), chsze02 (11 commits), Jsze22 (10 commits), limeconcretepowder (7 commits)

## Devpost submission (written by the team)

### Inspiration

It is always a gamble to know when to go to the fitness center or the library because you never know whether it is busy or not. In addition, due to poor web management, it is very hard to know whether a location is open or not.

### What it does

Tracks the busyness of the current UCSC location. It also checks whether the location is currently open.

### How we built it

We used Python for the backend and Kivy for the frontend. To look into the project, visit the GitHub for more information.

### Challenges we ran into

There wasn't a direct Google API for us to use to track busyness. We were planning to add all the dining halls to our app, but most dining halls do not have enough info we need to make it feasible.

### Accomplishments we're proud of

We managed to pull data from the Google Map's API and link it to our application. In addition, we were able to combine the data into an application that can be used by others.

### What we learned

How to integrate Kivy and API calls to create an application that can help students check the busyness of each location. Also, manage the data received from the Google APIs and convert them into information for the user.

### What's next

Create this application as an executable so that it is more user friendly Implement graphs to show trends in the area chosen. Add more locations that have the busyness feature Using app activities to further increase the accuracy of predicting traffic Users able to add locations

## README (from the GitHub repository)

# UCSC Location Busy Tracker
It will measure the busyness of people in a given location in UCSC.
Shows hours of operation, if it is currently open, and how busy it is currently.
It has a UI for ease of use; just click on the location and get the most recent data.

# Directions:
- Go to terminal and clone this git into your folder and type in the command below
-     git clone git@github.com:achang93/UCSC_Location_Busy_Tracker.git
- Go to terminal
  - Make sure pip3 is installed already
    - visit https://www.activestate.com/resources/quick-reads/how-to-install-and-use-pip3/ for more information
  - Install Kivy:
    -     pip3 install kivy
  - Install Google Maps:
    -     pip3 install googlemaps
  - Install Geopy:
    -     pip3 install geopy
- Make sure to create your own API key before running the program. With the use of the
API key, you can access the Google Maps APIs. To learn more about creating an API key,
visit https://developers.google.com/maps/documentation/javascript/get-api-key.

Once you have created an API key, you have to edit the "counter.py" file to input
your API key (it will be at line 61).

Once you have everything set up and installed, run the program counter.py on the terminal
with the command:

     python3 counter.py

# Front end:
To create the application for the user, we decided to use Kivy to help the user
access different locations to check the busyness and operational hours. We
implemented buttons that take the user to different locations.

# Back end:
We used the Google Maps API and Python to help gather data on how busy the location 
is at the current time and also whether it is operational at that time. We also
checked cases with respect to the time the user checked the information so we could check
whether it was opening on the same day or not. We also included a feature to tell the user
that the location will close in the next hour if the time they accessed it is within one 
hour of the closing time.

# Challenges:
- placing buttons in the proper area
- Adding images and aligning them to the corresponding buttons
- checking whether to use today's or tomorrow's operational hours with respect to the
  the time the user accessed the application
- not all locations in UCSC have the busyness feature, so the places that can be added
  are limited
- Many API calls decrease the performance of the application, so there is a 1-2 second
  delay after pressing a button

# Future Work:
- Add more features from the Google API into the application to help the user obtain
  more information about the location
- Decrease the execution time of each API call so that the user experience is smoother
- Add more UCSC locations that have or do not have the busyness feature, and then can be
  implemented if it does have that feature


## Detected evidence (automated analysis)

Indexed codebase: 7 recognized source files, 12 KB.
- Python (language) — detected in the code

## Codebase structure (from repository index)

### Files (12 of 12)

```
.gitmodules
.idea/.gitignore
.idea/gym_counter.iml
.idea/inspectionProfiles/profiles_settings.xml
.idea/misc.xml
.idea/modules.xml
.idea/vcs.xml
application.kv
counter.py
README.md
Small Island.otf
UCSC_populartimes.py
```

### Dependencies

No dependency index available.

### Recent commits (newest first)

- resize
- cosmetics
- finals changes
- finals changes
- Update counter.py
- Rename whatever.kv to application.kv
- Update README.md
- Update README.md
- Update README.md
- Update README.md
- Update README.md
- Update README.md
- Update README.md
- Update README.md
- Update README.md
- Update README.md
- Update README.md
- Update README.md
- Update README.md
- Update README.md

## Key source files (fetched from GitHub, selected and truncated for size)

### counter.py

```python
import kivy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.core.window import Window
from UCSC_populartimes import check_UCSC_fitness

Window.size = (700,700)
#Define different Screens
class FirstWindow(Screen):
    #def __init__(self, **kwargs):
    #    super(Screen, self).__init__(**kwargs)
    #    busy, hours, is_open = busy_and_hours("Fitness Center")
    #    self.add_widget(Label(text=busy))
    pass
class SecondWindow(Screen):
    pass
class ThirdWindow(Screen):
    pass

class FourthWindow(Screen):
    pass
class FifthWindow(Screen):
    pass

class WindowManager(ScreenManager):
    pass

kv = Builder.load_file('application.kv')
class MyGrid(Widget):


    name = ObjectProperty(None)
    pizza = ObjectProperty(None)
    '''def __init__(self, **kwargs):
        super(MainWidget, self).__init__(**kwargs)

        self.cols = 1

        self.top_grid = GridLayout()
        
        self.top_grid.cols = 2

        self.add_widget(Image(source = "Slug.png"))
        
        self.top_grid.add_widget(Label(text = "Student Name"))
        self.s_name = TextInput(multiline = False)
        self.top_grid.add_widget(self.s_name)


        self.top_grid.add_widget(Label(text = "Student Gender"))
        self.s_gender = TextInput()
        self.top_grid.add_widget(self.s_gender)

        self.add_widget(self.top_grid)

        self.press = Button(text = "CLICK ME", font_size = 40, size_hint_y = None, height = 100)
        self.press.bind(on_press = self.click_me)
        self.add_widget(self.press)'''

    def press(self):
        name = self.ids.name_input.text
        self.ids.name_label.text = name
        self.ids.name_input.text = ''
        
        '''if self.name.text != '':
            print(f"name of student is {self.name.text}")
            self.add_widget(Label(text = "thank you for your input"))

            self.s_name.text = '''''


class Awe(App):
    def build(self):
        return kv 
if __name__ == "__main__":
    Awe().run()


```

### UCSC_populartimes.py

```python
import googlemaps
import populartimes.populartimes as pt
import datetime


# gets the data from a location given the current day and hour
# then returns a value based on busyness
def get_busy_data(current_day, current_hour, api_key, place_id):
    # dictionary of data from a given location
    # usage: get_populartimes(api_key, place_id)
    location_data = pt.get_populartimes(api_key, place_id)


    # is the day of the week as an integer Monday-Friday: 0-6
    if not isinstance(current_day, int):
        raise ValueError("Invalid day")

    # in case place_id doesn't actually work
    try:
        # data for each day of the week
        # is an array of dictionaries
        all_week_data = location_data.get("populartimes")

    except:
        print("Invalid place_id: May not have data to read or doesn't exist")

    # is the data for the current day
    if current_day == 6:
        current_day_data = all_week_data[6]
    else:
        current_day_data = all_week_data[current_day]
    
    # data on the current hour
    current_hour_data = current_day_data.get("data")[current_hour]

    return current_hour_data


# accesses data from the hour to find out how relatively busy it is
def check_how_busy(data):
    if (data == 0):
        return "Closed"

    if (data < 25):
        return "Not that busy"

    if (data < 50):
        return "Not too busy"

    if (data < 75):
        return "A little busy"

    else:
        return "Busy"


# returns a string based on the location, day, and time
# also returns the opening hours
def busy_and_hours(location):
    time = int(datetime.datetime.now().strftime("%H"))
    day = int(datetime.datetime.today().weekday())

    # current API key, change if needed
    api_key = 'AIzaSyAdmbXNRA37N8dkheO_6A1t2DVhTt8I4tI'

    # place_id dictionary
    place_ids = {"McHenry Library": "ChIJk7eypKFBjoAR87wpNgAjQek",
                 "Fitness Center": "ChIJVRW6fKRBjoARlWkP543vP7g",
                 "Bay Tree Campus Store": "ChIJmWae1aBBjoARhPuzroaHOxg",
                 "Science and Engineering Library": "ChIJWeGcqQpBjoARohHiF-L7tB0"}

    # raise exception if the place_id isnt found
    try:
        place_id = place_ids.get(location)
    except:
        raise ValueError("Invalid location")

    # number based on how busy
    data = get_busy_data(day, time, api_key, place_id)

    if (data == 0):
        if day < 6:
            day = day + 1
        else:
            day = 0

    # get opening hours, just some mumble jumble
    map_client = googlemaps.Client(api_key)
    place_details = map_client.place(place_id)
    details_results = place_details.get('result')

    # data for opening hours
    opening_hours_data = details_results['opening_hours']
    print(details_results)
    is_open = opening_hours_data.get("open_now")

    # data for each weekday
    opening_hours_times = opening_hours_data.get("weekday_text")

    opening_hours = opening_hours_times[day]


    #if "Closed" in opening_hours:
    #    print("it went here")
    #    return check_how_busy(data), opening_hours[opening_hours.find("Closed"):], is_open, 0


    opening_hours = opening_hours[opening_hours.find(":") + 2:]
    opening_hours = ''.join(s for s in opening_hours if ord(s)>31 and ord(s)<126)
    opening_hours = opening_hours[0:opening_hours.find("M") + 1] + "-" + opening_hours[opening_hours.find("M") + 1:]

    # following code is to check whether the location closes in 1 hr or less
    y = opening_hours[opening_hours.find("M") + 1:]
    ending = opening_hours[-2:]
    y = str(y)
    y = y[1:]
    x = 0
    for i in range(len(y)):
        if y[i] == ':':
            break
        else:
            x += 1
    y = y[:x]

    if ending == 'PM':
        y = int(y) + 12
    # bottom if statement is to check whether it is 1 hr away from closing
    if y == "Open 24 hours":
        print("it went here1")
        return check_how_busy(data), "Open 24 hours", is_open, 0

    if int(y) - int(datetime.datetime.now().strftime("%H")) == 1:
        print("it went here2")
        return check_how_busy(data), opening_hours, is_open, 1

    print("it went here3")
    #print(time)
    #print(day)

    return check_how_busy(data), opening_hours, is_open, 0

def open_close(check_next, busy, hours, is_open, case):
    if is_open:
        if case == 1:

            if check_next + 1 == 13:
                check_next = 1
            ending = hours[-2:]
            hours = "Closing at " + str(check_next + 1) + ":00 " + ending
            return f'Open\n{busy}\n{hours}'
        else:
            return f'Open\n{busy}\n{hours}'
    else:
        if check_next < 12:
            return f"Closed\nToday's hours:\n{hours}"
        else:
            return f"Closed\nTomorrow's hours:\n{hours}"


def check_UCSC_fitness():

    busy, hours, is_open, case = busy_and_hours("Fitness Center")
    check_next = int(datetime.datetime.now().strftime("%H"))

    return open_close(check_next, busy, hours, is_open, case)
    


def check_UCSC_mchenry():
    #print("mchenry")
    busy, hours, is_open, case = busy_and_hours("McHenry Library")
    check_next = int(datetime.datetime.now().strftime("%H"))

    return open_close(check_next, busy, hours, is_open, case)



def check_UCSC_sne():
    #print("sne")
    busy, hours, is_open, case = busy_and_hours("Science and Engineering Library")
    check_next = int(datetime.datetime.now().strftime("%H")) 

    return open_close(check_next, busy, hours, is_open, case)

def check_UCSC_baytree():
    busy, hours, is_open, case = busy_and_hours("Bay Tree Campus Store")
    check_next = int(datetime.datetime.now().strftime("%H"))
    #print(datetime.datetime.today().weekday())
    if int(datetime.datetime.today().weekday()) == 5:
        return f'Closed\nTomorrow\'s hours: Closed'
    if int(datetime.datetime.today().weekday()) == 6:
        return f'Closed\nTomorrow\'s hours:\n{hours}'
    if is_open:
        if case == 1:
            if check_next+1 == 13:
                check_next = 1
     
[truncated — 527 more characters]
```

### .idea/misc.xml

```xml
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10" project-jdk-type="Python SDK" />
</project>
```

### .idea/vcs.xml

```xml
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="VcsDirectoryMappings">
    <mapping directory="" vcs="Git" />
    <mapping directory="$PROJECT_DIR$/populartimes" vcs="Git" />
  </component>
</project>
```

### .idea/modules.xml

```xml
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ProjectModuleManager">
    <modules>
      <module fileurl="file://$PROJECT_DIR$/.idea/gym_counter.iml" filepath="$PROJECT_DIR$/.idea/gym_counter.iml" />
    </modules>
  </component>
</project>
```

### .idea/inspectionProfiles/profiles_settings.xml

```xml
<component name="InspectionProjectProfileManager">
  <settings>
    <option name="USE_PROJECT_PROFILE" value="false" />
    <version value="1.0" />
  </settings>
</component>
```