defining an Enum instance in scalaz - scalaz

How would one do the analogue of the following in scalaz?
ghci> data Day = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday deriving (Eq, Show, Enum)
ghci> [Monday .. Wednesday]
[Monday,Tuesday,Wednesday]
For instance I should be able to do (Monday |-> Wednesday) and get List(Monday,Tuesday,Wednesday) once an Enum instance has been defined.
The Enum instances in AnyVal.scala seem pretty complicated. Is there a simpler way?

Related

G-sheets Conditional format, compare combined values of 3 cells ABC against combined EFG, and highlight rows that don't have a match

I'm trying to figure out conditional formatting to compare time logs, looking for outliers.
3 columns date, startTime, endTime to be compared against 3 similar columns
(Trying to highlight team members who worked alone during their logged hours)
I feel like I am dancing around a correct solution, but can't seem to nail it.
The simple version for conditional formatting that works for a single column is:
for column A: =COUNTIF($C$2:$C$9,$A2)=0
for column C: =COUNTIF($A$2:$A$10,$C2)=0
But, I am comparing 3 columns (date, startTime, endTime) from 1 person against a similar time log from different people...
Each member of a team is required to work with at least one other member at any given logged time. So, I only want the format change if the entry does not have a matching (date & start & end) from another person on the team.
Technically, I have up to 8 people in a team. But I think I can manage setting additional formatting after I understand the first set of columns.
I would compare by hand, but I have over 300 teams of up to 8 people. I have their logs on individual tabs, up to 8 per spreadsheet (one team). I added a total's sheet placing date, start, and end for person 1 in in columns a,b,c and person 2 in e,f,g etc....
I've tried many various combinations of countifs, countif with transpose, countif with join, countif with "&".
The most recent version was:
=COUNTIF(transpose($G$3:$J),transpose($B3:$E))=0
But, most, like this one, only seem to highlight if the date is different. If the date is the same and the hours differ it doesn't seem to see it.
I'm pulling time logs into my totals page with arrayformulas. I tried at one point to join the data into a string in a single column as it was being pulled in, but either the dates were getting changed to strings of numbers or the data was too squished and I couldn't read it clear enough while reviewing.
| x | date A | Start B | End C | D | date E | Start F | End G |
|:-:|:-------:|:-------:|:-----:|:-:|:-------:|:-------:|:-----:|
| *| 9/7/22 | 10am | 11am | | 9/7/22 | 2pm | 3pm |
| | 9/7/22 | 2pm | 3pm | | 9/10/22 | 2pm | 4pm |
| *| 9/8/22 | 2pm | 3pm | | 10/2/22 | 10am | 11am |
| | 9/10/22 | 2pm | 4pm | *| 10/3/22 | 9am | 11am |
| | 10/2/22 | 10am | 11am | | | | |
* = Highlight where not found in other lists
I tried an apps script, but had to authorize it for every spreadsheet hiding the functions from users not on review committee (roughly 300 spreadsheets).
The totals page will be hidden from the people logging their hours. I will not be reviewing the hours worked, there is a committee of 3 reviewing. I didn't want all 3 to have to authorize 300 spreadsheets.
//??????????????????????????????????????????????????????????
TLDR:
Please help me build a conditional format formula like:
(for column A: =COUNTIF($C$2:$C$9,$A2)=0)
that will take the combined values of 3 cells ABC and highlight any row that doesn't have a matching combined EFG.
//???????????????????????????????????????????????????????????
Any help would be greatly appreciated. Thanks!
If you could create a new column with this formula that joins E,F and G:
=arrayformula(IF(E2:E="","",E2:E&"|"&F2:F&"|"&G2:G))
I've set it in H:
Obviously you can hide that column, and yes, it is posible to do all inside the conditional formatting itself without that column but calculations will slow down a lot. You can change H to another column, just be sure that you change it in the formula too.
Then you can set this conditional formatting in range A2:C that joins each row and compares to that new column.
=IF($A2="","",if(iferror(match($A2&"|"&$B2&"|"&$C2,$H:$H,0),0),false,true))
See it here

MySQL Daily Appointment Scheduling Schema

I am looking to create a booking system. On one end you have a client looking to book an appointment and on the other end you have a provider who has a schedule that a client can book against
When signing up as a provider they are allowed to pick their days of work and hours. They have html check-boxes which represent which days they can select and once they select a day the hours are are displayed (drop-downs in angular) as you can see below
html schedule form
On the MySQL side I am thinking I can have a table which has a column for each day and have a comma separated list in there for the start time, end time, lunch time and lunch length
i.e. Provider selects Monday and Tuesday to work from the hours below
Provider 'Schedule' Table
|ScheduleID|ProviderID|Monday |Tuesday |Wednesday|Thursday|Friday|Saturday|Sunday|
|----------|----------|--------|--------|---------|--------|------|--------|------|
|1 | 2 |09:00am,|10:00am,| | | | | |
| | |08:30pm,|07:00pm,| | | | | |
| | |12:00pm,|01:00pm,| | | | | |
| | |30 min |60 min | | | | | |
|----------|----------|--------|--------|---------|--------|------|--------|------|
The table would have a schedule id and a provider id which links back to the "provider" table to link the provider to his schedule
Or is this better?
|-------------|-------------|----------|-----------|----------|------------|--------------|
| schedule_id | provider_id | week_day |start_time | end_time | lunch_time | lunch_length |
|-------------|-------------|----------|-----------|----------|------------|--------------|
| 1 | 1 | Monday | 06:00 AM | 08:00 PM | 12:30 PM | 60 |
|-------------|-------------|----------|-----------|----------|------------|--------------|
| 2 | 1 | Friday | 06:00 AM | 08:00 PM | 12:30 PM | 60 |
|-------------|-------------|----------|-----------|----------|------------|--------------|
| 3 | 2 | Tuesday | 06:00 AM | 08:00 PM | 12:30 PM | 60 |
|-------------|-------------|----------|-----------|----------|------------|--------------|
if not post something that is
Before I go into how I believe you should structure your Provider 'Schedule' Table, please make sure to, in the future, remove fluff.
More on fluff here.
It may serve you better to make the following changes:
make all column headers lowercase, as this might prevent errors if you attempt to query your database another way
change scheduleId to id
Instead of having seven columns, one for every day of the week, you could simply put a weekDay column that stores the value of that weekday
Then create columns for startTime, endTime, lunchTime and lunchLength
Finally, create a scheduleId column that ties together all the different weekday rows of someone's schedule to one provider
Some considerations:
Instead of having strings "Monday" or "Sunday" in the weekDay column you could instead insert 0..6, where 0 is a Sunday and 6 is a Saturday to make it more compatible with other languages
You could always just keep scheduleId in this table and create another table with the individual schedule days and link them with a foreign key, but this might prove to cause more problems than it's worth
Keeping that lunchLength as just an integer, as that will make everything easier
The reasoning behind splitting up the data as much as possible is because if you are querying using another language you might need to go through all the extra work of splitting those Monday and Tuesday columns if you just want the startTime for instance.
Hopefully the above is either a solution or allows you to consider another approach.
Here is a Java Android Library that you can convert into JavaScript: https://bitbucket.org/warwick/schedule_utils_demo/src/master/
Running the code in a client side language will save your server the burden as scheduling code is very inefficient.
Hope this helps.

Daily Time Schedule (MySQL)

This is what I have:
days_of_week
+----+-------------------+
| id | name |
+----+-------------------+
| 1 | Monday |
| 2 | Tuesday |
| 3 | Wednesday |
| 4 | Thursday |
| 5 | Friday |
| 6 | Satday |
| 7 | Sunday |
+----+-------------------+
time
+----------+-------------+
| id | time |
+----------+-------------+
| Integer | hh:mm:ss |
+----+-------------------+
schedule
+---------+---------+----------+---------+
| id | user_id | time_id | day_id |
+---------+---------+----------+---------+
| Integer | Integer | Integer | Integer |
+---------+---------+----------+---------+
Where should I put the activity column, i.e. Breakfast 08:30 for example. Now 'Breakfast' has to be stored somewhere here. I cannot figure out where for the moment, but if anyone knows how to correctly Normalize this please share with me, and tell my why you are doing it that way or recommend that. Thanks a lot in advance.
What I want to achieve:
Monday: Date of that day here
08:00 Breakfast
08:30 Something else
09:00 Introduction
Tuesday: Date of that day here
08:00 Breakfast
09:00 Hackathon begins
12:30 Lunch
You get it.
To clarify:
The user can select to add a schedule, this schedule is then created and includes schedule for what will happen during those selected days, for instance, if there is an Hackathon occurring for 3 days, the user can create a schedule for those three days, with time and activity that will take place. E.g. 08:00 Breakfast, 09:00 Introduction, 09:30 Equipment Installation
Found this:
Very normalized, Method for storing/displaying repeating weekly schedule
However, it's more for repeating weekly schedule, which is not what I want to achieve.
Are you going for a repeatable week on week schedule?
If not I'd consider dropping the days of week and time tables and using a standard DATETIME field. You could pop any restrictive measures in your model validation and it could also makes detecting clashes a bit easier.
Are you looking to regularly repeat activities?
If so I'd make an activities table and reference that from the schedule.
If not, I'd probably settle for a description and time.
SIMPLE
Schedule (id, description, datetime)
REPEATABLE ACTIVITIES
Schedule (id, activity_id, datetime)
Activity (id, description)
WEEK ON WEEK SCHEDULE (w/ repeatable activities)
Schedule (id, activity_id, day_of_week_id, time)
Activity (id, description)
Day_of_week (id, title)
Always go for the simplest option that fulfills your requirements!
Normalize! Since you are already doing it:
// others omitted
activity(id, description)
day(id, time_id, activity_id)
schedule(id, day_id)
I might miss something, but open for correction.

SQL Statement with the actual week

I have a table which look like this:
Date | Day | Ingredients
-------------------------------------------
2014-08-20 | Wednesday | Salt
2014-08-21 | Thursday | Sugar
2014-08-22 | Friday | Salt&Sugar
2014-08-28 | Thursday | Salt
And I want to have only the dates there are in one week. Should I make an extra column 'Week' with the number of the week or is there a solution where I can set the beginning and the end of a week to only have the actual week. So I have all rows from the actual week.
SELECT * FROM table WHERE *`Date is in the actual week`*
You mean to get the data of current week?
Use the YEARWEEK function.
SELECT * FROM your_table
WHERE YEARWEEK(`date`, 1) = YEARWEEK(CURRENT_DATE, 1)
Update:
Use mode 1 if the beginning of week is Monday.

Continue most recent value over a time range

I have this existing schema where a "schedule" table looks like this (very simplified).
CREATE TABLE schedule (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(45),
start_date date,
availability int(3),
PRIMARY KEY (id)
);
For each person it specifies a start date and percentage of work time available to spent on this project. That availability percentage implicitly continues until a newer value is specified.
For example take a project that lasts from 2012-02-27 to 2012-03-02:
id | name | start_date | availability
-------------------------------------
1 | Tom | 2012-02-27 | 100
2 | Tom | 2012-02-29 | 50
3 | Ben | 2012-03-01 | 80
So Tom starts on Feb., 27nd, full time, until Feb, 29th, from which on he'll be available only with 50% of his work time.
Ben only starts on March, 1st and only with 80% of his time.
Now the goal is to "normalize" this sparse data, so that there is a result row for each person for each day with the availability coming from the last specified day:
name | start_date | availability
--------------------------------
Tom | 2012-02-27 | 100
Tom | 2012-02-28 | 100
Tom | 2012-02-29 | 50
Tom | 2012-03-01 | 50
Tom | 2012-03-02 | 50
Ben | 2012-02-27 | 0
Ben | 2012-02-28 | 0
Ben | 2012-02-29 | 0
Ben | 2012-03-01 | 80
Ben | 2012-03-02 | 80
Think a chart showing the availability of each person over time, or calculating the "resource" values in a burndown diagram.
I can easily do this with procedural code in the app layer, but would prefer a nicer, faster solution.
To make this remotely effective, I recommend creating a calendar table. One that contains each and every date of interest. You then use that as a template on which to join your data.
Equally, things improve further if you have person table to act as the template for the name dimension of your results.
You can then use a correlated sub-query in your join, to pick which record in Schedule matches the calendar, person template you have created.
SELECT
*
FROM
calendar
CROSS JOIN
person
LEFT JOIN
schedule
ON schedule.name = person.name
AND schedule.start_date = (SELECT MAX(start_date)
FROM schedule
WHERE name = person.name
AND start_date <= calendar.date)
WHERE
calendar.date >= <yourStartDate>
AND calendar.date <= <yourEndDate>
etc
Often, however, it is more efficient to deal with it in one of two other ways...
Don't allow gaps in the data in the first place. Have a nightly batch process, or some other business logic that ensures all relevant dat apoints are populated.
Or deal with it in your client. Return each dimension in you report (data, and name) as seperate data sets to act as your templates, and then return the data as your final data set. Your client can itterate over the data and fill in the blanks as appropriate. It's more code, but can actually use less resource overall than trying to fill-the-gaps with SQL.
(If your client side code does this slowly, post another question examining that code. Provided that the data is sorted, this is acutally quite quick to do in most languages.)