Advertisement
Guest User

Untitled

a guest
May 31st, 2017
767
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.68 KB | None | 0 0
  1. import kivy
  2.  
  3. kivy.require('1.10.0')
  4.  
  5. from kivy.app import App
  6. from kivy.lang import Builder
  7. from kivy.uix.button import Button
  8. from kivy.uix.label import Label
  9. from kivy.uix.scrollview import ScrollView
  10. from kivy.uix.gridlayout import GridLayout
  11. from kivy.uix.floatlayout import FloatLayout
  12. from kivy.uix.textinput import TextInput
  13. from kivy.uix.screenmanager import ScreenManager, Screen
  14.  
  15.  
  16.  
  17.  
  18. class Item(object):
  19.     __slots__ = ["_canteen", "_submenu", "_dish", "_price"]
  20.  
  21.     def __init__(self, canteen, submenu, dish, price):
  22.         self._canteen = canteen
  23.         self._submenu = submenu
  24.         self._dish = dish
  25.         self._price = float(price)
  26.  
  27.     def getCanteen(self):
  28.         return self._canteen
  29.  
  30.     def getSubmenu(self):
  31.         return self._submenu
  32.  
  33.     def getDish(self):
  34.         return self._dish
  35.  
  36.     def getPrice(self):
  37.         return self._price
  38.  
  39.     def __len__(self):
  40.         return 1
  41.  
  42.     def __eq__(self, other):
  43.         return (self._dish == other._dish) and \
  44.                (self._price == other._price)
  45.  
  46.     def __repr__(self):
  47.         return "Item({0},{1},{2},{3})".format(self._canteen, self._submenu, self._dish, self._price)
  48.  
  49.     def __str__(self):
  50.         return "<{0},{1},{2},{3}>".format(self._canteen, self._submenu, self._dish, self._price)
  51.  
  52.  
  53. class Menu(object):
  54.     __slots__ = ["_canteen", "_result"]
  55.  
  56.     def __init__(self, canteen):
  57.         self._canteen = canteen
  58.         self._result = []
  59.         with open(self._canteen + '.csv', 'r') as f:
  60.             csvr = csv.reader(f)
  61.             for row in csvr:
  62.                 item = Item(row[0], row[1], row[2], row[3])
  63.                 self._result.append(item)
  64.  
  65.     def getCanteen(self):
  66.         return self._canteen
  67.  
  68.     def getSubmenus(self):
  69.         submenus = []
  70.         for item in self._result:
  71.             if item._submenu not in submenus:
  72.                 submenus.append(item._submenu)
  73.         return submenus
  74.  
  75.     def getDishes(self):
  76.         dishes = []
  77.         for item in self._result:
  78.             dishes.append(item._dish)
  79.         return dishes
  80.  
  81.     def getPrices(self):
  82.         prices = []
  83.         for item in self._result:
  84.             if item._price not in prices:
  85.                 prices.append(item._price)
  86.         return prices
  87.  
  88.     def specifySubmenus(self, submenus):
  89.         items = []
  90.         for item in self._result:
  91.             if item._submenu in submenus:
  92.                 items.append(item)
  93.         self._result = items
  94.  
  95.     def sortMenu(self):
  96.         return sorted(self._result, key=lambda x: x._price)
  97.  
  98.     def longestOrder(self, price):
  99.         sortedMenu = self.sortMenu()
  100.         minPrice = sortedMenu[0]._price
  101.         return int(price / minPrice)
  102.  
  103.     def shortestOrder(self, price):
  104.         sortedMenu = self.sortMenu()
  105.         maxPrice = sortedMenu[-1]._price
  106.         return int(price / maxPrice)
  107.  
  108.     def longOrder(self, price, sortedMenu=None):
  109.         if sortedMenu == None:
  110.             sortedMenu = self.sortMenu()
  111.         sum = 0
  112.         order = []
  113.         for item in sortedMenu:
  114.             if sum + item._price <= price:
  115.                 order.append(item._dish)
  116.                 sum += item._price
  117.         return order
  118.  
  119.     def lengthExact(self, length):
  120.         orders = []
  121.         maxLen = len(self.longOrder(7))
  122.         assert length == int(length) and 0 < length <= maxLen
  123.         sortedMenu = self.sortMenu()
  124.         maxPrice = 7 - (length - 1) * sortedMenu[0]._price
  125.         for item in sortedMenu:
  126.             if item._price > maxPrice:
  127.                 sortedMenu.remove(item)
  128.         allCombos = list(itertools.combinations_with_replacement(sortedMenu, length))
  129.         for combo in allCombos:
  130.             sum = 0
  131.             for item in combo:
  132.                 sum += item._price
  133.             if sum <= 7:
  134.                 orders.append(combo)
  135.         return orders
  136.  
  137.     def lengthRange(self, lower, upper):
  138.         allCombos = []
  139.         orders = []
  140.         maxLen = self.longestOrder(7)
  141.         assert lower == int(lower) and upper == int(upper) and 0 < lower < upper <= maxLen
  142.         sortedMenu = self.sortMenu()
  143.         for i in range(lower, upper + 1):
  144.             maxPrice = 7 - (i - 1) * sortedMenu[0]._price
  145.             for item in sortedMenu:
  146.                 if item._price > maxPrice:
  147.                     sortedMenu.remove(item)
  148.             allCombos += list(itertools.combinations_with_replacement(sortedMenu, i))
  149.         for combo in allCombos:
  150.             sum = 0
  151.             for item in combo:
  152.                 sum += item._price
  153.             if sum <= 7:
  154.                 orders.append(combo)
  155.         return orders
  156.  
  157.     def priceExact(self, price):
  158.         allCombos = []
  159.         orders = []
  160.         assert 0 < price <= 7
  161.         sortedMenu = self.sortMenu()
  162.         cheapestPrice = sortedMenu[0]._price
  163.         maxLen = self.longestOrder(price)
  164.         minLen = self.shortestOrder(price)
  165.         for i in range(minLen, maxLen + 1):
  166.             if i == 1:
  167.                 for item in self._result:
  168.                     if item._price == price:
  169.                         sortedMenu.remove(item)
  170.             else:
  171.                 maxPrice = price - (i - 1) * cheapestPrice
  172.                 for item in sortedMenu:
  173.                     if item._price > maxPrice:
  174.                         sortedMenu.remove(item)
  175.                 allCombos += list(itertools.combinations_with_replacement(sortedMenu, i))
  176.         for combo in allCombos:
  177.             sum = 0
  178.             for item in combo:
  179.                 sum += item._price
  180.             if sum == price:
  181.                 orders.append(combo)
  182.         return orders
  183.  
  184.     def priceRange(self, lower, upper):
  185.         allCombos = []
  186.         orders = []
  187.         assert 0 < lower <= upper <= 7
  188.         sortedMenu = self.sortMenu()
  189.         cheapestPrice = sortedMenu[0]._price
  190.         maxLen = self.longestOrder(upper)
  191.         minLen = self.shortestOrder(upper)
  192.         for i in range(minLen, maxLen + 1):
  193.             if i == 1:
  194.                 for item in self._result:
  195.                     if item._price >= lower and item._price <= upper:
  196.                         orders.append(item)
  197.             else:
  198.                 maxPrice = upper - (i - 1) * cheapestPrice
  199.                 for item in sortedMenu:
  200.                     if item._price > maxPrice:
  201.                         sortedMenu.remove(item)
  202.                 allCombos += list(itertools.combinations_with_replacement(sortedMenu, i))
  203.         for combo in allCombos:
  204.             sum = 0
  205.             for item in combo:
  206.                 sum += item._price
  207.             if sum >= lower and sum <= upper:
  208.                 orders.append(combo)
  209.         return orders
  210.  
  211.     def moreExact(self, order, price):
  212.         orderPrice = 0
  213.         for item in self._result:
  214.             if item._dish in order:
  215.                 orderPrice += item._price
  216.         assert orderPrice <= price <= 7
  217.         remaining = price - orderPrice
  218.         return self.priceExact(remaining)
  219.  
  220.     def moreRange(self, order, lower, upper):
  221.         orderPrice = 0
  222.         for item in self._result:
  223.             if item._dish in order:
  224.                 orderPrice += item._price
  225.         assert lower < upper <= 7 and orderPrice < upper
  226.         low = lower - orderPrice
  227.         high = upper - orderPrice
  228.         return self.priceRange(low, high)
  229.  
  230.     def append(self, value):
  231.         return self._result.append(value)
  232.  
  233.     def remove(self, value):
  234.         return self._result.remove(value)
  235.  
  236.     def getCopy(self):
  237.         return self._result.copy()
  238.  
  239.     def __iter__(self):
  240.         return iter(self._result)
  241.  
  242.     def __len__(self):
  243.         return len(self._result)
  244.  
  245.     def __repr__(self):
  246.         return "Menu({})".format(self._result)
  247.  
  248.     def __str__(self):
  249.         return "{}".format(self._result)
  250.  
  251.  
  252. class DiningButton(Button):
  253.     pass
  254.  
  255.  
  256. class DirectionButton(Button):
  257.     pass
  258.  
  259.  
  260. class ItemButton(Button):
  261.     pass
  262.  
  263.  
  264. class SubmenuButton(Button):
  265.     pass
  266.  
  267.  
  268. class HomeScreen(Screen):
  269.     pass
  270.  
  271.  
  272. class WhitmansMenu(Screen):
  273.     def initialize_list(self):
  274.         itemList = Menu('whitmans')
  275.         global allItems
  276.         allItems = itemList.getCopy()
  277.         return itemList
  278.  
  279.     def modify_list(self, itemList, value, dish):
  280.         if value == 'down':
  281.             for item in itemList:
  282.                 if dish == item.getDish():
  283.                     itemList.remove(item)
  284.                     break
  285.         else:
  286.             for item in allItems:
  287.                 if dish == item.getDish():
  288.                     itemList.append(item)
  289.                     break
  290.  
  291.     def modify_state(self, value, submenu, length):
  292.         if value == 'down':
  293.             for i in range(1, length + 1):
  294.                 button = self.ids[str(submenu) + '_item' + str(i)]
  295.                 button.state = 'down'
  296.         else:
  297.             for i in range(1, length + 1):
  298.                 button = self.ids[str(submenu) + '_item' + str(i)]
  299.                 button.state = 'normal'
  300.  
  301.  
  302. class ToolScreen(Screen):
  303.     pass
  304.  
  305.  
  306. class ToolButton(Button):
  307.     pass
  308.  
  309.  
  310. class InstructionsLabel(Label):
  311.     pass
  312.  
  313.  
  314. class SubLabel(Label):
  315.     pass
  316.  
  317.  
  318. class LengthExact(Screen):
  319.     def list(self):
  320.         app = App.get_running_app()
  321.         return app.itemList
  322.  
  323.  
  324. class LengthRange(Screen):
  325.     pass
  326.  
  327.  
  328. class PriceExact(Screen):
  329.     pass
  330.  
  331.  
  332. class PriceRange(Screen):
  333.     pass
  334.  
  335.  
  336. class MoreExact(Screen):
  337.     pass
  338.  
  339.  
  340. class MoreRange(Screen):
  341.     pass
  342.  
  343.  
  344.  
  345.  
  346.  
  347. class SnartoolsApp(App):
  348.     itemList = []
  349.  
  350.     def build(self):
  351.         Builder.load_string("""
  352. <WhitmansMenu>:
  353.    on_enter: app.itemList = root.initialize_list()
  354.    canvas.before:
  355.        Color:
  356.            rgba: 1, 1, 1, 1
  357.        Rectangle:
  358.            pos: self.pos
  359.            size: self.size
  360.    FloatLayout:
  361.        DirectionButton:
  362.            text: "Back"
  363.            pos_hint: {'left': 1, 'top': 1}
  364.            on_press:
  365.                root.manager.transition.duration = 0
  366.                root.manager.current = "home_screen"
  367.        DirectionButton:
  368.            text: "Done"
  369.            pos_hint: {'right': 1, 'top': 1}
  370.            on_press:
  371.                root.manager.transition.duration = 0
  372.                root.manager.current = "tool_screen"
  373.    BoxLayout:
  374.        orientation: "vertical"
  375.        pos_hint: {'top': 0.86}
  376.        InstructionsLabel:
  377.            text: "Select all menus and items to exclude from your order"
  378.        ScrollView:
  379.            GridLayout:
  380.                cols: 1
  381.                padding: 20
  382.                spacing: 5
  383.                size_hint_y: None
  384.                height: self.minimum_height
  385.                SubmenuButton:
  386.                    id: fryer
  387.                    text: 'Fryer'
  388.                    on_state: root.modify_state(fryer.state, 'fryer', 7)
  389.                ItemButton:
  390.                    id: fryer_item1
  391.                    text: 'Fried Green Beans'
  392.                    on_state: root.modify_list(app.itemList, fryer_item1.state, 'Fried Green Beans')
  393.                # A bunch more buttons below...
  394. <LengthExact>:
  395.    canvas.before:
  396.        Color:
  397.            rgba: 1, 1, 1, 1
  398.        Rectangle:
  399.            pos: self.pos
  400.            size: self.size
  401.    FloatLayout:
  402.        DirectionButton:
  403.            text: "Back"
  404.            pos_hint: {'left': 1, 'top': 1}
  405.            on_press:
  406.                root.manager.transition.duration = 0
  407.                root.manager.current = "tool_screen"
  408.    GridLayout:
  409.        cols: 1
  410.        pos_hint: {'top': 0.86}
  411.        BoxLayout:
  412.            orientation: "vertical"
  413.            InstructionsLabel:
  414.                text: "Enter the number of items you want to order"
  415.            SubLabel:
  416.                text: str(root.list())
  417.         """)
  418.  
  419.         screen_manager = ScreenManager()
  420.         screen_manager.add_widget(HomeScreen(name="home_screen"))
  421.         screen_manager.add_widget(WhitmansMenu(name="whitmans_menu"))
  422.         screen_manager.add_widget(ToolScreen(name="tool_screen"))
  423.         screen_manager.add_widget(LengthExact(name="length_exact"))
  424.         screen_manager.add_widget(LengthRange(name="length_range"))
  425.         screen_manager.add_widget(PriceExact(name="price_exact"))
  426.         screen_manager.add_widget(PriceRange(name="price_range"))
  427.         screen_manager.add_widget(MoreExact(name="more_exact"))
  428.         screen_manager.add_widget(MoreRange(name="more_range"))
  429.         screen_manager.current = "length_exact"
  430.  
  431.         return screen_manager
  432.  
  433.  
  434. SnartoolsApp().run()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement