Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added diversity, awesome traits, and added colors to graphs #9

Merged
merged 6 commits into from
Oct 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
49 changes: 49 additions & 0 deletions 200050103/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Hello-FOSS-LifeAudit
This project is a part of HELLO-FOSS: Celebration of Open Source by the Web and Coding Club. In this project we will be seeing the application of python in
developing an interesting, statistical simulation of our life in an online semester

### Guidelines
To contribute to this project there are not many prerequisites just that you should have a basic grasp over Python.You can go through [these resources](https://github.com/wncc/TSS-2021/tree/main/Python%20%26%20its%20Applications/Week-1) if you want to revise or learn Python.
**NOTE: before sending any pull request, rename your file to include your initials as - filename_RollNum.extension**.

## LifeAudit: Simulation Of Your Life In An Online Semester


Online semeseter has been sucking the joy out of our college life since the past 1-2 years for many of us. We all must have felt depressed, demotivated many times during this period. Overburdened by academics, running behind deadlines, mental and physical fitness going down the drain, we have all struggled to surrvive in this situation.

This simulation is an attempt to analyze if we managed our time well, set better priorities could we utilize this any better?. Its an interesting way to explore and see what works best for us even in such a situation.

### Problem Statement

#### The Code

There are 2 files here. One is [people.py](https://github.com/wncc/helloFOSS-21-LifeAudit/blob/main/people.py), this contains the code to describe the people class. This class contains the factors and characteristics describing a person such as his priorities, laziness, academic level, mental health etc. as well as the functions describes activities that the person does such as studying, exercising, relaxing etc.

The other file is [simulation.py](https://github.com/wncc/helloFOSS-21-LifeAudit/blob/main/simulation.py), this contains the code in which people are instantiatied, they perform various daily activities by calling the appropriate functions etc. Right now the simulation contains 100 people with exactly the same initial characteristics. The simulation runs and it plots some simple graphs from the results. The graphs contain the academic level, physical fitness, extracurricular development and mental health plotted daily for each person.

#### The Tasks
1. **Diversity**: Right now the model considers all the people have similar interests which is far from true. Add more classes of people for different types of people with different characteristics, different interests(see task-4) like coders, fitness freaks etc. These can inherit functions and attributes from the people class or can be altogether different classes. You can watch [this](https://www.youtube.com/watch?v=H2SQrZK2nvM&list=PLzMcBGfZo4-l1MqB1zoYfqzlj_HH-ZzXt&index=6) short video on inheritance if you don't know about it.


2. **Variation of Factors**: In the python file, change the variation of the factors so that the value remains between 0 and 100. The variation shouldn't just increment or decrement the value by a constant and it should depend on the current level as well. Consider the scenerio for academics for instance, initially you might study a lot but then you reach your saturation point and then the rate would decrease. Don't forget to model this situation! You can use the Gaussian function to model this or even simple if else commands or whatever function you think would be suitable.


3. **Breaking the Monotonous Routine**: No one can work monotonically and everyone needs a break from their routine at some point of time. So in this task try adding some features which help you to relax from your packed schedule. For instance, you have worked hard for 3-4 days continuously( that would mean the no. of hours that you study have been above a certain threshold for these few days) and now you want to take a break, relax and do minimal work.


4. **Individual Interests**: Each individual has a particular interest or an inclination towards a specific activity. Depending upon the interests, probability to attend a certain event can change drastically. The field of extracurricular activities can also be expanded accordingly. So instead of having the field of extracurricular level you can have fields for different kinds of activities like culturals, sports, tech etc. Also the activity "hobby" will also now change according to your interest. Depending on the interest other factors may get affected as well, like having sports as an hobby will automatically help push your physical fitness.


5. **Monthly Events**: A lot of events are conducted by the Institute Technical, Cultural and the Academic Council each month(unfortunately, online events for the 'COVID Batch'). Depending upon your interests, some of these events can affect the time spent on your daily activities. Major and the minor quizes also play a major role in the time distribution. So mainly there will be 2 types of events quizzes or events of clubs(Choose any 3 clubs you like). Now for quizzes one important factor to consider would be how the earlier academic level impacts and how the schedule changes when the quiz is just round the corner(A threshold of academic level might be needed to do well in the quiz and what can be observed is how people who are well prepared react differently to those who are not in the few days before the quiz). As for the events of the clubs you can use the interests described in task-4 to see in which events a person is likely to participate. Consider these situations and try to model them by showing how these events/quizes affect each person.

6. **External Factors**: You can try to incorporate the effect of weather and how it affects one's efficiency for eg. On a sunny day people don't exercise or on a rainy day (which is literally everyday here) the person feels sulky and doesn't feel like studying. On a rainy day, you might need to cancel your plan of playing outdoor sports which affects the physical fitness metric in the simulation.

7. **Representing the results**: As you can see in the code right now it simply plots graphs of each factor for each person everyday. However its hard to draw any kind of conclusions from such graphs. So you should try and improve the ways results are being represented. Try drawing scatter plots between factors to see correlatons between them. You can draw these plots considering weekly averages of people instead of daily. After task 5 you can compare the plots specifically of the days close to the event to see its impact.

### Note: The above mentioned tasks are not hard guidelines and are just to give you a nudge to think in the right direction. So feel free to put your creativity & critical thinking to the work and make some awesome simulations!

Join our [Discord server](https://discord.gg/Rkh6e6F2) for discussing your doubts.
***

<p align="center">Created with :heart: by <a href="https://wncc-iitb.org/">WnCC</a></p>

Binary file added 200050103/__pycache__/people.cpython-37.pyc
Binary file not shown.
109 changes: 109 additions & 0 deletions 200050103/people.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
## Class for people defining various parameters such as acads, extracurriculars, tech, cult etc
## Various member functions are defined indicating the effect of a particular activity
import random
import math
types_of_people = 2 #change this variable with more number of people
class people():
def __init__(self):
self.academics = 20
self.extracur = 15
self.technical = 15
self.cult = 15
self.fitness = 75
self.mental_health = 75
self.happiness = 80
self.probs = [0.6, 0.2, 0.2]
self.laziness = 0.5

#max and min:essentially, ranges for the attribute values
self.technical_max = 100
self.fitness_min = 0
self.fitness_max = 200
self.laziness_max = 3
self.academics_max = 100
self.academics_min = 0

def adjust(self):
if self.technical>self.technical_max:
self.technical = self.technical_max
if self.fitness < self.fitness_min:
self.fitness = self.fitness_min
if self.fitness > self.fitness_max:
self.fitness = self.fitness_max
if self.laziness > self.laziness_max:
self.laziness = self.laziness_max
if self.academics < self.academics_min:
self.academics = self.academics_min
if self.academics > self.academics_max:
self.academics = self.academics_max

def choose(self,min,max,parameter): #selects value increment or decrement as per tanh function's slope
#parameter = (max-min)tanh(x)+min
dx = 0.5
return (max-min)*(1-math.tanh(parameter))*dx

def study(self):
self.academics += self.choose(0,self.academics_max,self.academics)
self.fitness -= self.choose(self.fitness_min,self.fitness_max,self.fitness)
self.adjust()

def hobby(self):
self.extracur += 0.5
self.mental_health += 0.7
self.adjust()

def relax(self):
self.mental_health += 0.7
self.fitness -= self.choose(self.fitness_min,self.fitness_max,self.fitness)
self.adjust()

def exercise(self):
self.fitness -= self.choose(self.fitness_min,self.fitness_max,self.fitness)
self.mental_health += 0.5
self.adjust()

class coder(people):
def __init__(self):
super().__init__()
self.academics += 5
self.extracur += 2
self.technical += 15
self.cult -= 5
self.fitness -= 20
self.mental_health -= 5
self.happiness += 5
self.laziness += 1 # ;)
self.probs = [0.5, 0.1, 0.2, 0.05, 0.1, 0.05]

def coding_practice(self):
self.extracur += 0.5
self.fitness -= self.choose(self.fitness_min,self.fitness_max,self.fitness)
self.adjust()

def comp_coding(self):
self.extracur += 0.5
self.fitness -= 0.5

success = (random.randint(0,10000) <= (self.technical*100)) #success on based on technical skill
if success:
self.happiness += 1
self.mental_health += 0.25
else:
self.happiness -= 1
self.mental_health -= 1.25
self.laziness += 0.05
self.adjust()

def contributive_coding(self):
self.extracur += 0.5
self.technical += self.choose(0,self.technical_max,self.technical)
self.fitness -= self.choose(self.fitness_min,self.fitness_max,self.fitness)

pr_accept = (random.randint(0,10000) <= ((self.technical+self.extracur)*100)) #success on based on technical skill and extracur
if pr_accept:
self.happiness += 1.25
self.mental_health += 0.25
else:
self.happiness -= 1
self.mental_health -= 1.25
self.adjust()
174 changes: 174 additions & 0 deletions 200050103/simulation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
import random as rnd ## For generating random choices/numbers
import matplotlib.pyplot as plt ## For plotting the graphs
import seaborn as sns ## For data visualization and analysis
import sys
import people #Importing the people module
import math

def on_press(event):
"""
Close sim on pressing any key
"""
sys.exit(0)
#instances
pop = people.people()
cod = people.coder()
#Initializing the people
population = []
for i in range(100):
#randomly choosing the type of person to be added
if rnd.randint(0,10)%people.types_of_people==0:
population.append(people.people())
else:
population.append(people.coder())

## Loop runs for each day in a month and each day the activities array is emptied
fig, ax = plt.subplots()

for days in range(30):
activities = [[]]*100
for hours in range(24):
for i in range(100):
person = population[i]
if type(person)==type(pop):
if(hours >= rnd.randint(8, 8+person.laziness*4) or hours <= 17): #Depending on how lazy the person is, it decides when the person starts his day

## Randomly choosing between study, hobby and relax according to their weights defined earlier

work = rnd.choices(['s', 'h', 'r'], person.probs)
if work == ["s"]:
activities[i].append("studied")
person.study()
elif work == ["h"]:
activities[i].append("hobby")
person.hobby()
else:
activities[i].append("relaxed")
person.relax()
elif((hours > 4 and hours <= 7) or (hours < 20 and hours > 17)):
# For exercising in morning or evening, depends on the laziness of the person
e = rnd.choices(['e', 'ne'], [1-person.laziness, person.laziness])[0]
if e == "e":
person.exercise()
if hours == 23 and (activities[i].count("studied")/len(activities[i])) > 0.4:
#Studying above a certain limit in a day can cause some amount of mental health detrioration
person.mental_health -= 1

person.academics -= 0.02 #To simulate forgetfullnes, each day you tend to a forget a few things from days back
person.adjust()
elif type(person)==type(cod):
if(hours >= rnd.randint(8, 8+math.floor(person.laziness)*4) or hours <= 17): #Depending on how lazy the person is, it decides when the person starts his day

## Randomly choosing between study, hobby and relax according to their weights defined earlier

work = rnd.choices(['s', 'h', 'r','cprac','com_code','contib_code'], person.probs)
if work == ["s"]:
activities[i].append("studied")
person.study()
elif work == ["h"]:
activities[i].append("hobby")
person.hobby()
elif work == ["r"]:
activities[i].append("relaxed")
person.relax()
elif work == ["cprac"]:
activities[i].append("coding practice")
person.comp_coding()
elif work == ["com_code"]:
activities[i].append("competitive coding")
person.relax()
else:
activities[i].append("open source contributions")
person.contributive_coding()
elif((hours > 4 and hours <= 7) or (hours < 20 and hours > 17)):
# For exercising in morning or evening, depends on the laziness of the person
e = rnd.choices(['e', 'ne'], [1-person.laziness, person.laziness])[0]
if e == "e":
person.exercise()
if hours == 23 and (activities[i].count("studied")/len(activities[i])) > 0.4:
#Studying above a certain limit in a day can cause some amount of mental health detrioration
person.mental_health -= 1

person.academics -= 0.02 #To simulate forgetfullnes, each day you tend to a forget a few things from days back
person.adjust()

## Appending the arrays according to the activities and the choices in a day

acads = []
for person in population:
acads.append(person.academics)
extracurs = []
for person in population:
extracurs.append(person.extracur)

mental_healths = []
for person in population:
mental_healths.append(person.mental_health)

physical_healths = []
for person in population:
physical_healths.append(person.fitness)

## Plotting the results

plt.subplot(4, 1, 1)
plt.plot(range(100), acads, color='darkblue')
plt.xlabel("Person")
plt.ylabel("Academic Level")
plt.subplot(4, 1, 2)
plt.plot(range(100), extracurs, color='green')
plt.xlabel("Person")
plt.ylabel("Extracurricular Level")
plt.subplot(4, 1, 3)
plt.plot(range(100), mental_healths, color='orange')
plt.xlabel("Person")
plt.ylabel("Mental Health")
plt.subplot(4, 1, 4)
plt.plot(range(100), physical_healths, color='red')
plt.xlabel("Person")
plt.ylabel("Physical Fitness")
plt.tight_layout()
fig.canvas.mpl_connect("key_press_event", on_press) #Detect key press
plt.draw()
plt.pause(1)
fig.clf()

## Compile data and draw the final graph at the end of the month

acads = []
for person in population:
acads.append(person.academics)
extracurs = []
for person in population:
extracurs.append(person.extracur)

mental_healths = []
for person in population:
mental_healths.append(person.mental_health)

physical_healths = []
for person in population:
physical_healths.append(person.fitness)

## Plotting the results


plt.subplot(4, 1, 1)
plt.plot(range(100), acads, color='darkblue')
plt.xlabel("Person")
plt.ylabel("Academic Level")
plt.subplot(4, 1, 2)
plt.plot(range(100), extracurs, color='green')
plt.xlabel("Person")
plt.ylabel("Extracurricular Level")
plt.subplot(4, 1, 3)
plt.plot(range(100), mental_healths, color='orange')
plt.xlabel("Person")
plt.ylabel("Mental Health")
plt.subplot(4, 1, 4)
plt.plot(range(100), physical_healths, color='red')
plt.xlabel("Person")
plt.ylabel("Physical Fitness")
plt.tight_layout()
fig.canvas.mpl_connect("key_press_event", on_press) #Detect key press
plt.show()