air travel – Is there a way to track historical averages of flight costs?

Covid-19 has shaken up the flight industry, and I noticed some flights to far off tourist destinations that seem like great deals, e.g. US to Italy for $1000 round trip. If they are so good, I’d like to take advantage while possible; though it would be preferred to wait until Covid-19 is gone to fly. To help with the decision-making process, is there any database of historical flight costs, so I can truly check if these are good prices, or just the usual?

go – Calculate intersection point of 2 or 3 moving averages

I want to calculate the intersection point, in time, of 2 or 3 moving averages.

To solve this problem I decided to transform the moving average(ma) data into geometrical lines and calculate the intersection point via the formula for lines in the slope/intercept form.

X coordinate is the unix timestamp of the ma, the Y coordinate is the value of the ma.

Converting the intersection point to datetime format gives me the exact time of intersection.

The data is coming in from a websocket and it is based on a granularity setting.

In order to build the line representations of the moving averages a logic layer is needed to correctly set and update the X,Y coordinates of the lines.

Would like to know if the mutation operations on the line data can be written in a cleaner way.

Also any other improvement suggestions are welcome.

geometry.go

package geometry                                                                                                                                                                                                     
                                                                                                                                                                                                                     
//Line represents a geometrical line                                                                                                                                                                                 
type Line struct {                                                                                                                                                                                                   
  PointA    Point                                                                                                                                                                                                    
  PointB    Point                                                                                                                                                                                                    
  slope     float64                                                                                                                                                                                                  
  intercept float64                                                                                                                                                                                                  
}                                                                                                                                                                                                                    
                                                                                                                                                                                                                     
func NewLine(a Point, b Point) Line {                                                                                                                                                                                
  line := Line{                                                                                                                                                                                                      
    PointA: a,                                                                                                                                                                                                       
    PointB: b,                                                                                                                                                                                                       
  }                                                                                                                                                                                                                  
                                                                                                                                                                                                                     
  line.calculateSlope()                                                                                                                                                                                              
  line.calculateIntercept()                                                                                                                                                                                          
                                                                                                                                                                                                                     
  return line                                                                                                                                                                                                        
}                                                                                                                                                                                                                    
                                                                                                                                                                                                                     
func (l *Line) calculateSlope() {                                                                                                                                                                                    
  l.slope = (l.PointA.Y - l.PointB.Y) / (l.PointA.X - l.PointB.X)                                                                                                                                                    
}                                                                                                                                                                                                                    
                                                                                                                                                                                                                     
func (l *Line) Slope() float64 {                                                                                                                                                                                     
  return l.slope                                                                                                                                                                                                     
}                                                                                                                                                                                                                    
                                                                                                                                                                                                                     
func (l *Line) calculateIntercept() {                                                                                                                                                                                
  l.intercept = l.PointA.Y - (l.slope * l.PointA.X)                                                                                                                                                                  
}                                                                                                                                                                                                                    
                                                                                                                                                                                                                     
//Point represents a single Point on the x,y axis                                                                                                                                                                    
type Point struct {                                                                                                                                                                                                  
  X,                                                                                                                                                                                                                 
  Y float64                                                                                                                                                                                                          
}                                                                                                                                                                                                                    
                                                                                                                                                                                                                     
//IntersctionPoint return the intersection point of two lines.                                                                                                                                                       
//Calculation uses slope/intercept line form                                                                                                                                                                         
func IntersectionPoint(l1, l2 Line) Point {                                                                                                                                                                          
  //line slope intercept form equation                                                                                                                                                                               
  //y - y coordinate, x - x coordinate                                                                                                                                                                               
  //m - slope, b intercept                                                                                                                                                                                           
  //y = mx + b                                                                                                                                                                                                       
                                                                                                                                                                                                                     
  //intersection equation for line definitions y = 3x-3 and y = 2.3x+4                                                                                                                                               
  //(3x-3 = 2.3x+4), (3x-2.3x = 4+3)                                                                                                                                                                                 
  //0.7x = 7, (x = 7/0.7), x = 10                                                                                                                                                                                    
  leftSide := l1.slope + (l2.slope * -1)                                                                                                                                                                             
  rightSide := l2.intercept + (l1.intercept * -1)                                                                                                                                                                    
                                                                                                                                                                                                                     
  x := rightSide / leftSide                                                                                                                                                                                          
  y := l1.slope*x + l1.intercept                                                                                                                                                                                     
                                                                                                                                                                                                                     
  return Point{X: x, Y: y}                                                                                                                                                                                           
} 

intersector.go

package intersector

import (
  "fmt"
  "intersector/geometry"
  "time"
)

const (
  up   = 1
  down = -1
)

type Average struct {
  Value     float64
  Timestamp int
}

//intersector builds lines from the received moving average data
//and calculates their intersection point. max 3 lines
type intersector struct {
  input chan ()Average
}

func NewIntersector(input chan ()Average) intersector {
  return intersector{
    input: input,
  }
}

//point is a wrapper around geometry.Point
//adds timestamp field needed for tracking and placing
//moving average values as x,y coordinates
type point struct {
  point     geometry.Point
  timestamp int
}

func newPoint(x, y float64, timestamp int) point {
  return point{
    point: geometry.Point{
      X: x,
      Y: y,
    },
    timestamp: timestamp,
  }
}

//line is a wrapper around geometry.Line
//adds helper fields for capturing point data
//from data stream
type line struct {
  geometry  geometry.Line
  pointA    point
  pointB    point
  direction int
}

func newLine(a, b point) *line {
  return &line{
    geometry: geometry.NewLine(a.point, b.point),
    pointA:   a,
    pointB:   b,
  }
}

//update updates pointA or pointB of a line base on the timestamp of the average
func (line *line) update(average Average) bool {
  //data refers to pointA of the line definition
  //will not trigger once pointB is defined
  if line.pointA.timestamp == average.Timestamp {
    line.pointA.point.Y = average.Value
    return true
  }

  //checks if pointB is defined yet, if not, inititialises pointB and creates the line
  if line.pointB == (point{}) {
    line.pointB = newPoint(float64(average.Timestamp), average.Value, average.Timestamp)
    line.geometry = geometry.NewLine(line.pointA.point, line.pointB.point)
    return true
  }

  if average.Timestamp == line.pointB.timestamp {
    line.pointB.point.Y = average.Value
    return true
  }

  //collecting data on pointB has finished. line is complete
  //return false as there is nothing to update for this line
  if average.Timestamp != line.pointB.timestamp {
    return false
  }

  return true
}

func (l *line) setDirection(direction int) {
  l.direction = direction
}

func getDirection(line geometry.Line) int {
  horizon := 0.00

  if line.Slope() <= horizon {
    return down
  }

  return up
}

func (z intersector) Calculate() {
  incompleteLines := make(map(int)*line)
  completeLines := make(map(int)*line)

  for {
    if averages, ok := <-z.input; ok {

      for index, average := range averages {
        if line, ok := incompleteLines(index); !ok {
          pointA := newPoint(float64(average.Timestamp), average.Value, average.Timestamp)
          pointB := point{}

          incompleteLines(index) = newLine(pointA, pointB)
          continue
        } else {
          if updated := line.update(average); !updated {
            pointA := newPoint(float64(line.pointA.timestamp), line.pointA.point.Y, line.pointA.timestamp)
            pointB := newPoint(float64(line.pointB.timestamp), line.pointB.point.Y, line.pointB.timestamp)

            completeLines(index) = newLine(pointA, pointB)
            incompleteLines(index) = newLine(line.pointB, point{})
          }
        }
      }

      //QUESTION::
      //Can the same be done with a for loop avoiding the code duplication for lines A and B?
      switch len(completeLines) {
      case 2:
        lineA := completeLines(0)
        lineB := completeLines(1)
        intersection := geometry.IntersectionPoint(lineA.geometry, lineB.geometry)

        //check if the intersection point is within the origin coordinates of the lines
        //intersections that occur outside of the lline definition are not important
        if intersection.X >= lineA.geometry.PointA.X && intersection.X <= lineB.geometry.PointB.X {
          //only print intersections that do not occur in the same direction. lines can intersect multiple times going upward or downward
          if lineA.direction != getDirection(lineA.geometry) {
            lineA.setDirection(getDirection(lineA.geometry))
            fmt.Printf("Line1 interesects Line2 at: %v Y: %v X: %v Direction: %vn", t(intersection.X), intersection.Y, intersection.X, getDirection(lineA.geometry))
          }
        }
      case 3:
        lineA := completeLines(0)
        lineB := completeLines(1)
        lineC := completeLines(2)

        intersection1 := geometry.IntersectionPoint(lineA.geometry, lineB.geometry)
        intersection2 := geometry.IntersectionPoint(lineA.geometry, lineC.geometry)
        intersection3 := geometry.IntersectionPoint(lineB.geometry, lineC.geometry)

        //check if the intersection point is within the origin coordinates of the lines
        //intersections that occur outside of the lline definition are not important
        if intersection1.X >= lineA.geometry.PointA.X && intersection1.X <= lineB.geometry.PointB.X {
          //only print intersections that do not occur in the same direction. lines can intersect multiple times going upward or downward
          if lineA.direction != getDirection(lineA.geometry) {
            lineA.setDirection(getDirection(lineA.geometry))
            fmt.Printf("Line1 interesects Line2 at: %v Y: %v X: %v Direction: %vn", t(intersection1.X), intersection1.Y, intersection1.X, getDirection(lineA.geometry))
          }
        }

        if intersection2.X >= lineA.geometry.PointA.X && intersection2.X <= lineC.geometry.PointB.X {
          if lineC.direction != getDirection(lineC.geometry) {
            lineC.setDirection(getDirection(lineC.geometry))
            fmt.Printf("Line1 interesects Line3 at: %v Y: %v X: %v Direction: %vn", t(intersection2.X), intersection2.Y, intersection2.X, getDirection(lineA.geometry))
          }
        }

        if intersection3.X >= lineB.geometry.PointA.X && intersection3.X <= lineC.geometry.PointB.X {
          if lineB.direction != getDirection(lineB.geometry) {
            lineB.setDirection(getDirection(lineB.geometry))
            fmt.Printf("Line2 interesects Line3 at: %v Y: %v X: %v Direction: %vn", t(intersection3.X), intersection3.Y, intersection3.X, getDirection(lineB.geometry))
          }
        }
      }
    } else {
      return
    }
  }
}

//converts unix time to string time
func t(timestamp float64) string {
  t := int64(timestamp / 1000)
  tm := time.Unix(t, 0)
  return tm.Format(time.RFC3339)
}

postgresql – postgres read query resample time series data for hourly averages

I am new to SQL trying to learn how to do read queries on time series data. Can someone give me a tip on how to resample interval time series data to hourly averages on the postgres read query?

My table is named building_data where there are a few columns named time, metric, value, kv_tags, m_tags

time is my date/time stamp column where I am trying to see if I can resample the data in the value column into hourly averages. The WHERE in the query below is to filter out for a specific device that I am interested in looking at the data. I apologize if that doesn’t make sense.

For a first timer this sql query appears to work but its not incorporating some process to resample the data in hourly averages, any tips greatly appreciated.

SELECT
  "time" AS "time",
  metric AS metric,
  value,
  kv_tags,
  m_tags
FROM building_data
WHERE kv_tags->'equip_name' = '["35201"]' AND 
  m_tags IS NOT NULL
ORDER BY time desc limit 1000

pandas – Broadcasting daily averages to different years

I am looking to broadcast the daily averages over a year (365 values) to different years, so that a particular day will have the same value for different years including the leap ones. I could do it easily for the monthly data with ‘reindex’ and the ‘ffill’ and ‘bfill’ but have been getting NaNs for daily data. Below is the sample code:

import pandas as pd
import datetime as dt
import numpy as np

julians  = np.arange(1, 366,1)
date_str = (dt.datetime.strptime(days, '%j').date() for days in julians)
date_ind = (strs.strftime('%m-%d') for strs in date_str)
dfs =pd.DataFrame(np.arange(1, 366, 1), index = date_ind)

dfs_ref = pd.DataFrame(np.arange(1, 1462,1 ), index = pd.date_range('2015-01-01', '2018-12-31', freq = 'D'))  # the reference index

df_fin = dfs.reindex(dfs_ref.index).ffill() #df_fin = dfs.reindex(dfs_ref.index).bfill() # neither works, I get all NaNs

Can anyone help me out with this?

Product of averages

Let $(x_1,…,x_n)$ and $(y_1,…,y_n)$ be two different tuples of positive reals such that $x_1timesdotstimes x_n=y_1timesdotstimes y_n = c$.
Is it true that
$$left(frac{x_1+y_1}{2}right)timescdotstimes left(frac{x_n+y_n}{2}right) > c?$$

I think this should follow from a concavity argument, perhaps on the function $f(x_1,…,x_n) = x_1timescdotstimes x_n$, but not sure how exactly.

solution verification – why is there a large difference in total averages between these two methods to find the average of two different data sets?

So I was working with averages between two sets of numbers and found some issues with the solution that my two methods got. Below is the dataset

Column A Column B
2 1
3 2
1 3
2 1
3 2
1 3
2 1
3 2
1 3
2 1

The first method is to average column A (2) and average column B (1.9). Take those two numbers and divide them into each other (1.9/2.0) and I get .95

The second method is I take each number from column A and divide them to the number right next to them in column B (ie, 2/1, then 3/2, then, 1/3, etc…) to get a new set of number and put it in column C.

Column C
.5
.66
3
.5
.66
3
.5
.66
3
.5

Then I add all values in Column C and divide by 10 (finding the average of column C) and I get 1.298. Why is there a large variance between the first method and second method? Did I do something wrong in my calculation for each methods?

google sheets – How to create a formula to look at my most recent past 20 scores in a column and averages the lowest 8 scores

In Google Sheets I would like to create a formula to look at my most recent past 20 scores in a column and averages the lowest 8 scores.

In another post I found the following formula that will average my 8 most recent scores. However, I need it to look at my most recent 20 scores and average the lowest 8.

Here was the formula I found:

=AVERAGE(QUERY(SORT(K3:K, ROW(K3:K)*ISNUMBER(K3:K),0),"select * LIMIT 8"))