Merge branch 'master' of github.com:IvanMalison/dotfiles

This commit is contained in:
Ivan Malison 2018-04-18 23:13:38 -07:00
commit d3c954cbc3
No known key found for this signature in database
GPG Key ID: 62530EFBE99DC2F8
9 changed files with 311 additions and 227 deletions

2
.gitmodules vendored
View File

@ -1,6 +1,6 @@
[submodule "dotfiles/config/taffybar/taffybar"] [submodule "dotfiles/config/taffybar/taffybar"]
path = dotfiles/config/taffybar/taffybar path = dotfiles/config/taffybar/taffybar
url = ../taffybar.git url = ../../travitch/taffybar.git
[submodule "dotfiles/xmonad/xmonad"] [submodule "dotfiles/xmonad/xmonad"]
path = dotfiles/config/xmonad/xmonad path = dotfiles/config/xmonad/xmonad
url = ../xmonad.git url = ../xmonad.git

View File

@ -18,10 +18,12 @@ executable imalison-taffybar
, containers , containers
, directory , directory
, filepath , filepath
, gtk-strut
, gi-gtk , gi-gtk
, glib , glib
, gtk3>=0.14.8 , gtk3>=0.14.8
, gtk-sni-tray , gtk-sni-tray
, hslogger
, mtl , mtl
, haskell-gi-base , haskell-gi-base
, process , process

View File

@ -8,16 +8,10 @@ packages:
git: git@github.com:willdonnelly/dyre.git git: git@github.com:willdonnelly/dyre.git
commit: 11412752b483135e0c151ab90be17b217f837c4b commit: 11412752b483135e0c151ab90be17b217f837c4b
extra-dep: true extra-dep: true
- location:
git: git@github.com:IvanMalison/gtk-traymanager.git
commit: 517b24722b2cdab2dadbafa882ffcb6b8a1d01ff
extra-dep: true
- location: ../xmonad/xmonad-contrib - location: ../xmonad/xmonad-contrib
extra-dep: true extra-dep: true
- location: ../../../../Projects/status-notifier-item - location: ../../../../Projects/status-notifier-item
extra-dep: true extra-dep: true
- location: ../../../../Projects/haskell-dbus
extra-dep: true
- location: ../../../../Projects/gtk-sni-tray - location: ../../../../Projects/gtk-sni-tray
extra-dep: true extra-dep: true
- location: - location:
@ -27,19 +21,24 @@ packages:
- gtk - gtk
extra-dep: true extra-dep: true
extra-deps: extra-deps:
- spool-0.1
- X11-xft-0.3.1 - X11-xft-0.3.1
- gio-0.13.4.1 - dbus-1.0.0
- libxml-sax-0.7.5
- rate-limit-1.1.1
- time-units-1.0.0
- xml-helpers-1.0.0
- gi-dbusmenugtk3-0.4.1
- gi-dbusmenu-0.4.1 - gi-dbusmenu-0.4.1
- gi-dbusmenugtk3-0.4.1
- gi-gdk-3.0.15 - gi-gdk-3.0.15
- gi-gdkpixbuf-2.0.15 - gi-gdkpixbuf-2.0.15
- gi-gtk-3.0.21 - gi-gdkx11-3.0.2
- gi-gio-2.0.16 - gi-gio-2.0.16
- gi-gtk-3.0.21
- gi-pango-1.0.16 - gi-pango-1.0.16
resolver: lts-10.5 - gi-xlib-2.0.2
- gio-0.13.4.1
- gtk-strut-0.1.2.0
- gtk-traymanager-1.0.1
- libxml-sax-0.7.5
- rate-limit-1.1.1
- spool-0.1
- time-units-1.0.0
- xml-helpers-1.0.0
resolver: lts-11.4
allow-newer: true allow-newer: true

@ -1 +1 @@
Subproject commit f7673d90530183aa97d86000dc3160ca784fa492 Subproject commit 1c2dbadc40ce23a54a465bc072b1fce208c9be7e

View File

@ -11,9 +11,10 @@ import Data.List
import Data.List.Split import Data.List.Split
import qualified Data.Map as M import qualified Data.Map as M
import Data.Maybe import Data.Maybe
import Debug.Trace
import Foreign.ForeignPtr import Foreign.ForeignPtr
import Foreign.Ptr import Foreign.Ptr
import qualified GI.Gtk.Objects.Widget as GI import qualified GI.Gtk as GI
import qualified "gtk3" Graphics.UI.Gtk as Gtk import qualified "gtk3" Graphics.UI.Gtk as Gtk
import qualified "gtk3" Graphics.UI.Gtk.Abstract.Widget as W import qualified "gtk3" Graphics.UI.Gtk.Abstract.Widget as W
import qualified "gtk3" Graphics.UI.Gtk.Layout.Table as T import qualified "gtk3" Graphics.UI.Gtk.Layout.Table as T
@ -23,10 +24,13 @@ import System.Directory
import System.Environment import System.Environment
import System.FilePath.Posix import System.FilePath.Posix
import System.Glib.GObject import System.Glib.GObject
import System.IO
import System.Information.CPU import System.Information.CPU
import System.Information.EWMHDesktopInfo import System.Information.EWMHDesktopInfo
import System.Information.Memory import System.Information.Memory
import System.Information.X11DesktopInfo import System.Information.X11DesktopInfo
import System.Log.Handler.Simple
import System.Log.Logger
import System.Process import System.Process
import System.Taffybar import System.Taffybar
import System.Taffybar.Battery import System.Taffybar.Battery
@ -34,14 +38,13 @@ import System.Taffybar.IconImages
import System.Taffybar.LayoutSwitcher import System.Taffybar.LayoutSwitcher
import System.Taffybar.MPRIS2 import System.Taffybar.MPRIS2
import System.Taffybar.NetMonitor import System.Taffybar.NetMonitor
import System.Taffybar.Pager
import System.Taffybar.SimpleClock import System.Taffybar.SimpleClock
import System.Taffybar.SimpleConfig
import System.Taffybar.Systray import System.Taffybar.Systray
import System.Taffybar.ToggleMonitor import System.Taffybar.ToggleMonitor
import System.Taffybar.Widgets.PollingGraph import System.Taffybar.Widgets.PollingGraph
import System.Taffybar.WindowSwitcher import System.Taffybar.WindowSwitcher
import System.Taffybar.WorkspaceHUD import System.Taffybar.WorkspaceHUD
import System.Taffybar.WorkspaceSwitcher
import Text.Printf import Text.Printf
import Text.Read hiding (lift) import Text.Read hiding (lift)
import Unsafe.Coerce import Unsafe.Coerce
@ -123,28 +126,6 @@ underlineWidget cfg buildWidget name = do
return $ Gtk.toWidget t return $ Gtk.toWidget t
movableWidget builder =
do
-- Delay creation of the widget or else failure from trying to get screen
widVar <- MV.newEmptyMVar
let moveWidget = do
isEmpty <- MV.isEmptyMVar widVar
when isEmpty $
do
putwid <- builder
MV.putMVar widVar putwid
wid <- MV.readMVar widVar
hbox <- Gtk.hBoxNew False 0
parent <- Gtk.widgetGetParent wid
if isJust parent
then
Gtk.widgetReparent wid hbox
else
Gtk.containerAdd hbox wid
Gtk.widgetShowAll hbox
return $ Gtk.toWidget hbox
return moveWidget
myFormatEntry wsNames ((ws, wtitle, wclass), _) = myFormatEntry wsNames ((ws, wtitle, wclass), _) =
printf "%s: %s - %s" wsName (head $ splitOn "\NUL" wclass) wtitle printf "%s: %s - %s" wsName (head $ splitOn "\NUL" wclass) wtitle
where where
@ -157,18 +138,28 @@ getInterfaces = do
addClass klass action = do addClass klass action = do
widget <- action widget <- action
widgetSetClass widget klass lift $ widgetSetClass widget klass
return widget return widget
(buildWidgetCons, _) = mkWidget (buildWidgetCons, _) = mkWidget
buildSNITray = do buildSNITray = do
GI.Widget trayGIWidgetMP <- buildTrayWithHost -- XXX: this won't work for multiple taffybars because it will attempt to
-- register a second host with a name that already exists on the dbus tray.
-- Need to take an approach similar to that of gtk-sni-tray to get that to
-- work.
GI.Widget trayGIWidgetMP <- buildTrayWithHost GI.OrientationHorizontal
wrapNewGObject mkWidget (castPtr <$> disownManagedPtr trayGIWidgetMP) wrapNewGObject mkWidget (castPtr <$> disownManagedPtr trayGIWidgetMP)
logDebug = do
handler <- streamHandler stdout DEBUG
logger <- getLogger "System.Taffybar"
saveGlobalLogger $ setLevel DEBUG logger
main = do main = do
interfaceNames <- getInterfaces interfaceNames <- getInterfaces
homeDirectory <- getHomeDirectory homeDirectory <- getHomeDirectory
logDebug
let resourcesDirectory = homeDirectory </> ".lib" </> "resources" let resourcesDirectory = homeDirectory </> ".lib" </> "resources"
inResourcesDirectory file = resourcesDirectory </> file inResourcesDirectory file = resourcesDirectory </> file
highContrastDirectory = highContrastDirectory =
@ -232,25 +223,29 @@ main = do
-- ] -- ]
, showWorkspaceFn = hideEmpty , showWorkspaceFn = hideEmpty
, updateRateLimitMicroseconds = 100000 , updateRateLimitMicroseconds = 100000
, updateOnWMIconChange = True
, debugMode = False , debugMode = False
, labelSetter = workspaceNamesLabelSetter , labelSetter = workspaceNamesLabelSetter
} }
netMonitor = netMonitorMultiNew 1.5 interfaceNames netMonitor = netMonitorMultiNew 1.5 interfaceNames
pagerConfig =
defaultPagerConfig
{useImages = True, windowSwitcherFormatter = myFormatEntry}
-- makeUnderline = underlineWidget myHUDConfig -- makeUnderline = underlineWidget myHUDConfig
pgr <- pagerNew pagerConfig -- pgr <- pagerNew pagerConfig
-- tray2 <- movableWidget tray -- tray2 <- movableWidget tray
let hud = buildWorkspaceHUD myHUDConfig pgr let hud = buildWorkspaceHUD myHUDConfig
los = layoutSwitcherNew pgr los = layoutSwitcherNew defaultLayoutSwitcherConfig
wnd = windowSwitcherNew pgr wnd = windowSwitcherNew defaultWindowSwitcherConfig
taffyConfig = simpleTaffyConfig =
defaultTaffybarConfig defaultSimpleTaffyConfig
{ startWidgets = [hud, los, addClass "WindowSwitcher" wnd] { startWidgets = [hud, los, addClass "WindowSwitcher" wnd]
, endWidgets = , endWidgets =
[ batteryBarNewWithFormat defaultBatteryConfig "$percentage$% ($time$) - $status$" 1.0 [ batteryBarNewWithFormat defaultBatteryConfig "$percentage$% ($time$) - $status$" 1.0
||||||| merged common ancestors
, endWidgets =
[ batteryBarNew defaultBatteryConfig 1.0
=======
, centerWidgets = []
, endWidgets = map lift
[ batteryBarNew defaultBatteryConfig 1.0
>>>>>>> b44e57a9f4ec822e99649b1ccc5516cbcbad4fb8
, makeContents clock "Cpu" , makeContents clock "Cpu"
-- , makeContents systrayNew "Cpu" -- , makeContents systrayNew "Cpu"
, makeContents buildSNITray "Cpu" , makeContents buildSNITray "Cpu"
@ -261,10 +256,10 @@ main = do
] ]
, barPosition = Top , barPosition = Top
, barPadding = 5 , barPadding = 5
, barHeight = (underlineHeight myHUDConfig + windowIconSize myHUDConfig + 10) , barHeight = (underlineHeight myHUDConfig + windowIconSize myHUDConfig + 15)
, widgetSpacing = 0 , widgetSpacing = 0
} }
withToggleSupport taffyConfig dyreTaffybar $ handleDBusToggles $ toTaffyConfig simpleTaffyConfig
-- Local Variables: -- Local Variables:
-- flycheck-ghc-args: ("-Wno-missing-signatures") -- flycheck-ghc-args: ("-Wno-missing-signatures")

View File

@ -1,134 +0,0 @@
style "taffybar-default" {
color["black"] = "#000000"
color["white"] = "#ffffff"
color["green"] = "#4caf50"
color["yellow"] = "#ffeb3b"
color["orange"] = "#f4511e"
color["blue"] = "#2196f3"
color["red"] = "#F44336"
color["dgrey"] = "#212121"
color["ldgrey"] = "#333333"
color["mgrey"] = "#808080"
color["lldgrey"] = "#424242"
color["lgrey"] = "#bdbdbd"
color["teal"] = "#00796b"
color["bgrey"] = "#37474F"
color["bgreyl"] = "#546E7A"
color["activeWS"] = @yellow
color["visibleWS"] = @red
color["base"] = @black
color["accent1"] = @dgrey
color["accent2"] = @ldgrey
bg[NORMAL] = @black
fg[NORMAL] = @white
text[NORMAL] = @black
fg[PRELIGHT] = @yellow
}
style "taffybar-active-window" = "taffybar-default" {
fg[NORMAL] = @white
}
style "taffybar-notification-button" = "taffybar-default" {
text[NORMAL] = @red
fg[NORMAL] = @red
}
style "taffybar-workspace-border-active" = "taffybar-default" {
bg[NORMAL] = @yellow
}
style "taffybar-workspace-border-visible" = "taffybar-default" {
bg[NORMAL] = @orange
}
style "taffybar-workspace-border-empty" = "taffybar-default" {
bg[NORMAL] = @blue
}
style "taffybar-workspace-border-hidden" = "taffybar-default" {
bg[NORMAL] = @blue
}
style "taffybar-icon-urgent" = "taffybar-default" {
bg[NORMAL] = @yellow
}
style "taffybar-icon-active" = "taffybar-default" {
bg[NORMAL] = @teal
}
style "taffybar-icon-minimized" = "taffybar-default" {
bg[NORMAL] = @red
}
style "taffybar-workspace-contents-active" = "taffybar-default" {
bg[NORMAL] = @dgrey
}
style "taffybar-workspace-contents-visible" = "taffybar-default" {
bg[NORMAL] = @black
}
style "taffybar-hover-button" = "taffybar-default" {
bg[ACTIVE] = @yellow
bg[NORMAL] = @black
bg[PRELIGHT] = @yellow
text[PRELIGHT] = @yellow
}
style "blue" = "taffybar-default" {
bg[NORMAL]= @blue
}
style "orange" = "taffybar-default" {
bg[NORMAL]= @orange
}
style "red" = "taffybar-default" {
bg[NORMAL]= @red
}
style "yellow" = "taffybar-default" {
bg[NORMAL]= @yellow
}
style "green" = "taffybar-default" {
bg[NORMAL]= @green
}
style "teal" = "taffybar-default" {
bg[NORMAL]= @teal
}
style "bgrey" = "taffybar-default" {
bg[NORMAL]= @bgrey
}
widget "Taffybar*" style "taffybar-default"
widget "*WindowTitle*" style "taffybar-active-window"
widget "*NotificationCloseButton" style "taffybar-notification-button"
widget "*Workspace-underline*-active*" style "taffybar-workspace-border-active"
widget "*Workspace-contents*-active*" style "taffybar-workspace-contents-active"
widget "*Workspace-contents*-visible*" style "taffybar-workspace-contents-visible"
widget "*Workspace-underline*-visible*" style "taffybar-workspace-border-visible"
widget "*Workspace-underline*-empty*" style "taffybar-workspace-border-empty"
widget "*Workspace-underline*-hidden*" style "taffybar-workspace-border-hidden"
widget "*Workspace-Border*-active*" style "taffybar-workspace-border-active"
widget "*Workspace-Container-*-active*" style "taffybar-default"
widget "*Workspace-Border*-visible*" style "taffybar-workspace-border-visible"
widget "*Workspace-Container-*-visible*" style "taffybar-default"
widget "*Workspace-icon*-urgent*" style "taffybar-icon-urgent"
widget "*Workspace-icon*-active*" style "taffybar-icon-active"
widget "*Workspace-icon*-minimized*" style "taffybar-icon-minimized"
widget "*WorkspaceHUD-*" style "taffybar-hover-button"
widget "*WorkspaceHUD-*" style "taffybar-hover-button"
widget "*clock-underline*" style "taffybar-workspace-border-active"
widget "*tray-underline*" style "taffybar-workspace-border-hidden"
widget "*blue-underline*" style "blue"
widget "*red-underline*" style "red"
widget "*yellow-underline*" style "yellow"
widget "*orange-underline*" style "orange"
widget "*green-underline*" style "green"
widget "*teal-underline*" style "teal"
widget "*bgrey-underline*" style "bgrey"

View File

@ -2134,6 +2134,12 @@ I don't use auto-complete at all, so I have set up a hook to automatically disab
(global-flycheck-mode)) (global-flycheck-mode))
:diminish flycheck-mode) :diminish flycheck-mode)
#+END_SRC #+END_SRC
* straight
#+BEGIN_SRC emacs-lisp
(use-package straight
:config
(setq straight-vc-git-auto-fast-forward t))
#+END_SRC
* Major Modes * Major Modes
** Programming ** Programming
<<programminglanguages>> <<programminglanguages>>

View File

@ -1,6 +1,8 @@
#!/usr/bin/env zsh #!/usr/bin/env sh
export SYSTEMD_COLORS=0 export SYSTEMD_COLORS=0
term=${ROFI_SYSTEMD_TERM-termite -e}
default_action=${ROFI_SYSTEMD_DEFAULT_ACTION-"list_actions"}
function user_units { function user_units {
SYSTEMD_COLORS=0 systemctl --user list-unit-files | tail -n +2 | head -n -2 | SYSTEMD_COLORS=0 systemctl --user list-unit-files | tail -n +2 | head -n -2 |
@ -16,21 +18,31 @@ enable="Alt+e"
disable="Alt+d" disable="Alt+d"
stop="Alt+k" stop="Alt+k"
restart="Alt+r" restart="Alt+r"
tail="Alt+t"
list_actions="Alt+l"
all_actions="enable
disable
stop
restart
tail
list_actions"
function select_service_and_act { function select_service_and_act {
result=$(rofi -dmenu -i -p "systemd unit: " \ result=$(rofi -dmenu -i -p "systemd unit: " \
-kb-custom-1 "${enable}" \ -kb-custom-1 "${enable}" \
-kb-custom-2 "${disable}" \ -kb-custom-2 "${disable}" \
-kb-custom-3 "${stop}" \ -kb-custom-3 "${stop}" \
-kb-custom-4 "${restart}") -kb-custom-4 "${restart}" \
-kb-custom-5 "${tail}" \
-kb-custom-6 "${list_actions}")
rofi_exit="$?" rofi_exit="$?"
selection="$(echo $result | sed -n 's/ \+/ /gp')"
action="restart"
case "$rofi_exit" in case "$rofi_exit" in
1) 1)
exit action="exit"
exit 1
;; ;;
10) 10)
action="enable" action="enable"
@ -41,17 +53,53 @@ function select_service_and_act {
12) 12)
action="stop" action="stop"
;; ;;
13)
action="restart"
;;
14)
action="tail"
;;
15)
action="list_actions"
;;
*)
action="$default_action"
;;
esac esac
service_name="$(printf $selection | awk '{ print $1 }' | tr -d ' ')" selection="$(echo $result | sed -n 's/ \+/ /gp')"
is_user="$(printf $selection | awk '{ print $3 }' )" service_name="$(echo $selection | awk '{ print $1 }' | tr -d ' ')"
is_user="$(echo $selection | awk '{ print $3 }' )"
case "$is_user" in case "$is_user" in
user*) user*)
systemctl "$action" --user "$service_name" user_arg="--user"
command="systemctl $user_arg"
;; ;;
system*) system*)
sudo systemctl "$action" "$service_name" user_arg=""
command="sudo systemctl"
;;
*)
command="systemctl"
esac
to_run="$(get_command_with_args)"
echo "Running $to_run"
eval "$to_run"
}
function get_command_with_args {
case "$action" in
"tail")
echo "$term 'journalctl $user_arg -u $service_name -f'"
;;
"list_actions")
action=$(echo "$all_actions" | rofi -dmenu -i -p "Select action: ")
get_command_with_args
;;
*)
echo "$command $action $service_name"
;; ;;
esac esac
} }

View File

@ -0,0 +1,168 @@
#!/usr/bin/env python
import heapq
from collections import namedtuple
BuyOpportunity = namedtuple(
'BuyOpportunity',
['trans_yield', 'start', 'end']
)
def maximize_profit(num_transactions, prices):
minima, maxima = find_extrema(prices)
opp_queue, reverse_opp_queue = make_opportunity_queues(
minima, maxima, prices,
)
if not opp_queue:
return []
largest_segment = opp_queue[0][1]
# Segments will be kept in sorted order
segments = [largest_segment]
# Remove any reverse yields that are greater than the largest actual yield
# since they can never be realized anyway.
while (reverse_opp_queue and reverse_opp_queue[0][1].trans_yield >=
largest_segment.trans_yield):
heapq.heappop(reverse_opp_queue)
def try_rev_opp():
# It is okay to definitely pop here even though we don't know that we
# can actually use the opp for the following reason:
# Since the rev opp queue was selected OVER that of the opp queue, we
# KNOW that the bounding segment that includes this rev opp must have
# already been selected if it is going to be included at all (since it
# must have greater yield).
_, rev_opp_can = heapq.heappop(reverse_opp_queue)
for (seg_index, split_seg) in enumerate(segments):
if split_seg.end >= rev_opp_can.end:
# Since segments is sorted, this must be the correct segment
break
else:
return
if split_seg.start <= rev_opp_can.start:
# We found the containing segment
left_yield = prices[rev_opp_can.start] - prices[split_seg.start]
right_yield = prices[split_seg.end] - prices[rev_opp_can.end]
left_segment = BuyOpportunity(left_yield, split_seg.start, rev_opp_can.start)
right_segment = BuyOpportunity(right_yield, rev_opp_can.end, split_seg.end)
segments.pop(seg_index)
segments.insert(seg_index, left_segment)
segments.insert(seg_index + 1, right_segment)
def try_opp():
_, opp = heapq.heappop(opp_queue)
if not segments:
segments.append(opp)
insertion_index = 0
for (index, seg) in enumerate(segments):
if seg.start >= opp.start:
insertion_index = index
break
else:
insertion_index = len(segments)
seg = None
previous_seg = segments[insertion_index - 1] if insertion_index > 0 else None
if ((seg is None or seg.start >= opp.end) and
(previous_seg is None or previous_seg.end <= opp.start)):
# There is no overlap, so we can insert
segments.insert(insertion_index, opp)
else:
pass
while (opp_queue or reverse_opp_queue) and len(segments) < num_transactions:
if not reverse_opp_queue:
try_opp()
elif not opp_queue:
try_rev_opp()
else:
opp_can = opp_queue[0][1]
rev_opp_can = reverse_opp_queue[0][1]
if rev_opp_can.trans_yield > opp_can.trans_yield:
try_rev_opp()
else:
try_opp()
return segments
def make_opportunity_queues(minima, maxima, prices):
opp_queue = []
reverse_opp_queue = []
for min_index, minimum in enumerate(minima):
for max_index, maximum in enumerate(maxima):
transaction_yield = prices[maximum] - prices[minimum]
if transaction_yield < 0:
# We can ignore this pair because the transaction has negative
# yield.
continue
# minimum comes before maximum in time
if minimum < maximum:
# Transaction yield is made negative because heapq is a min-heap
heapq.heappush(
opp_queue, ((-transaction_yield, maximum - minimum), BuyOpportunity(
transaction_yield, minimum, maximum,
)),
)
else:
heapq.heappush(
reverse_opp_queue, (-transaction_yield, BuyOpportunity(
transaction_yield, maximum, minimum,
))
)
return opp_queue, reverse_opp_queue
def find_extrema(prices):
maxima = []
minima = []
length_of_prices = len(prices)
if length_of_prices < 2:
return minima, maxima
upwards = None
last = prices[0]
for (index, price) in enumerate(prices):
if price < last:
if upwards is True:
maxima.append(index - 1)
elif upwards is None:
# We set the starting price as a maximum, but theres no point
# since we would really never buy.
maxima.append(0)
pass
upwards = False
elif price > last:
if upwards is False:
minima.append(index - 1)
elif upwards is None:
# The starting value is a minimum
minima.append(0)
upwards = True
last = price
if upwards is True:
maxima.append(length_of_prices - 1)
elif upwards is False:
minima.append(length_of_prices - 1)
return minima, maxima
if __name__ == '__main__':
print (maximize_profit(10, [0, 1, 3, 2, 3, 0, 10, 12, 1, 2, 3, 2, 0, 2, 4, 3, 6, 4, 14, 1, 0, 2, 4, 5, 4, 5, 6]))
print [
BuyOpportunity(trans_yield=1, start=0, end=1),
BuyOpportunity(trans_yield=12, start=2, end=4),
BuyOpportunity(trans_yield=2, start=5, end=7),
BuyOpportunity(trans_yield=6, start=9, end=11),
BuyOpportunity(trans_yield=6, start=12, end=13),
BuyOpportunity(trans_yield=10, start=14, end=15),
BuyOpportunity(trans_yield=5, start=17, end=20),
BuyOpportunity(trans_yield=2, start=21, end=23),
]