By: F11-03
Since: Feb 2020
Licence: MIT
1. Introduction
1.1. Software Overview
FoodieBot is a campus food application which can help users look for food they want, by recommending the canteens nearest to them, providing randomized food suggestions, helping users plan their budget and provide info on food around NUS. FoodieBot is the one stop application to solve all meal decision problems on NUS.
1.2. Purpose
The purpose of this document is to describe the architecture and system design of the FoodieBot. This documentation is for anyone who wishes to understand more about FoodieBot and how it works.
1.3. Audience
Our target users are students, staff and tourists, in general anyone who comes to or visits NUS. In particular, for the indecisive user, this application can give a random food suggestion tailored to each user based on their budget and/ or past food selections etcetera.
2. Setting up
Our application is being managed by the dependency management tool Gradle. The project is available at https://github.com/AY1920S2-CS2103T-F11-3/main. After cloning the repository, you can follow these steps:
For IntelliJ users
-
Run gradle build.
-
Run gradle run.
3. Definitions
Defined below are common terminology that will be used frequently throughout this document.
- Context
-
Refers to which state the application is in. Use interchangeably with user interface.
4. Design
4.1. Architecture
The Architecture Diagram given above explains the high-level design of the App. Given below is a quick overview of each component.
|
Tip
|
The .puml files used to create diagrams in this document can be found in the diagrams folder.
Refer to the Using PlantUML guide to learn how to create and edit diagrams.
|
-
At app launch: Initializes the components in the correct sequence, and connects them up with each other.
-
At shut down: Shuts down the components and invokes cleanup methods where necessary.
Commons
represents a collection of classes used by multiple other components.
The following class plays an important role at the architecture level:
-
LogsCenter
: Used by many classes to write log messages to the App’s log file.
The rest of the App consists of four components.
Each of the four components
-
Defines its API in an
interface
with the same name as the Component. -
Exposes its functionality using a
{Component Name}Manager
class.
For example, the Logic
component (see the class diagram given below) defines it’s API in the Logic.java
interface and exposes its functionality using the LogicManager.java
class.
How the architecture components interact with each other
The Sequence Diagram below shows how the components interact with each other for the scenario where the user issues the command favorites set 1
.
favorites set 1
commandThe sections below give more details of each component.
4.2. UI component
API : Ui.java
The UI consists of a MainWindow
that is made up of parts e.g.CommandBox
, ResultDisplay
, CanteenListPanel
, StatusBarFooter
etc. All these, including the MainWindow
, inherit from the abstract UiPart
class.
The UI
component uses JavaFx UI framework. The layout of these UI parts are defined in matching .fxml
files that are in the src/main/resources/view
folder. For example, the layout of the MainWindow
is specified in MainWindow.fxml
The UI
component,
-
Executes user commands using the
Logic
component. -
Listens for changes to
Model
data so that the UI can be updated with the modified data.
4.3. Logic component
API :
Logic.java
-
Logic
uses theFoodieBotParser
class to parse the user command. -
This results in a
Command
object which is executed by theLogicManager
. -
The command execution can affect the
Model
(e.g. adding a person). -
The result of the command execution is encapsulated as a
CommandResult
object which is passed back to theUi
. -
In addition, the
CommandResult
object can also instruct theUi
to perform certain actions, such as displaying help to the user.
|
Note
|
The lifeline for DeleteCommandParser should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
|
4.4. Model component
API : Model.java
The Model
,
-
stores a
UserPref
object that represents the user’s preferences. -
stores the FoodieBot data.
-
exposes an unmodifiable
ObservableList<Canteen>
that can be 'observed' e.g. the UI can be bound to this list so that the UI automatically updates when the data in the list change. -
does not depend on any of the other three components.
|
Note
|
As a more OOP model, we can store a Tag list in FoodieBot , which Canteen can reference. This would allow FoodieBot to only require one Tag object per unique Tag , instead of each Canteen needing their own Tag object. An example of how such a model may look like is given below. |
4.5. Storage component
API : Storage.java
The Storage
component,
-
can save
UserPref
objects in json format and read it back. -
can save the FoodieBot data in json format and read it back.
4.6. Common classes
Classes used by multiple components are in the seedu.foodiebot.commons
package.
4.7. Design Considerations
4.7.1. Aspect: Executing similar tasks but for different objects
e.g. Selecting canteens, stalls, food.
-
Alternative 1 (current choice): Create a context class that executes commands based on the context the user is in.
-
Pros: Higher quality user interface, user does not need to remember so many commands.
-
Cons: More difficult to implement.
-
-
Alternative 2: Create different commands for different objects
-
Pros: Easier to implement. There will not be any chance of overlapping commands
-
Cons: Reduce quality of user interface as user has to remember many different commands.
-
5. Implementation
5.1. List Command
The list command is facilitated by ListCommandParser
.
It extends FoodieBotParser
to handle list canteen commands.
The following activity diagram summarizes what happens when a user executes a list command:
5.1.1. List Command Implementation
It implements the following operations:
-
ListCommand#execute()
— Updates the canteen list to show all the canteens or filtered by location.
|
Note
|
ListCommand extends Command with Command#execute() .
|
-
ListCommandParser#arePrefixesPresent()
— Checks if the prefixes specified inparse()
are found in the command entered by the user. -
ListCommandParser#parse()
— Identifies if prefixes have been specified and handles them respectively.
For example, if ListCommand has the nearest block name passed through as a parameterlist f\com1
, ListCommand will filter the canteen list with the given block name withnew ListCommand("com1")
The following sequence diagram shows how the list operation works:
5.1.2. List Design Considerations
Aspect: User command format
-
Alternative 1 (current choice):
list f/com
-
Pros: Uses only a prefix to get the intended functionality with list.
-
Cons:
f/
is an optional prefix, user might forget that it exists as no error is shown in the command result box
-
-
Alternative 2: find nearest
BLOCK_NAME
-
Pros: It is not required to remember any prefix.
-
Cons: Can be confusing whether find shows the list of canteens, food, or location of the canteen on campus. Find has to be followed by nearest otherwise it does not come natural to sort by distance.
-
5.2. Budget Command
The budget
command is implemented by the BudgetCommand
class.
This command is accessed by the LogicManager#execute()
to set the budget for the user or to view the current budget of the user.
The following activity diagram illustrate the different scenario for the budget command:
5.2.1. Budget Command Implementation
-
The
LogicManager
first executesFoodieBotParser
to create aBudgetCommandParse
object. -
BudgetCommandParse
then parse the budget command to determine if the action of the budget isset
,view
or invalid.
This process returns a newBudgetCommand
object. -
The
LogicManager
then access thenBudgetCommand#execute()
to determine the type of execution. -
If the action is
set
then thebudget
object saves the user input accordingly. -
If the action is
view
then the budge is retrieve from the storage. -
The
BudgetCommand#execute()
returns aCommandResult
object to theLogicManger
.
Below is the sequence diagram that summarizes what happens during the execution of the budget
command:
5.2.2. Budget Design Considerations
Aspect: Budget view
shows the transactions screen
-
Alternative 1 (current choice):
Budget view
displays the current budget in the command feedback panel.-
Pros: Budget can be viewed anywhere in FoodieBot.
-
Cons: -
-
-
Alternative 2:
-
Pros: Can set a realistic budget after looking at past spendings.
-
Cons: Increased the coupling of budget and transactions but the intended functionality is different. The user may not want to type budget to rate a food item.
-
5.3. Enter Command
The enter
command is implemented by either the EnterCanteenCommand
class or the EnterStallCommand
class.
These commands are accessed by the LogicManager#execute()
to switch the user interface accordingly base on where the user is at.
The following activity diagram illustrates the different scenario for the enter command:
5.3.1. Enter Command Implementation
-
The
LogicManager
first executesFoodieBotParser
which parses the user input into aParserContext
to determine if the user is currently on the main context. -
If the user has input
enter
on the main context, it creates aEnterCanteenCommandParser
object that parses in the user input to determine which canteen to enter. -
Otherwise if the user has Input
enter
on the stall context, it creates aEnterStallCommandParser
object that parses in the user input to determine which stall to enter This process returns a newEnterCanteenCommand
/EnterStallCommand
object accordingly to theLogicManager
. -
The
LogicManager
then accessEnterCanteenCommand#execute()
/EnterStallCommand#execute()
to switch the current display to the stalls/food available within the selected canteen/stall. -
Both
EnterCanteenCommand#execute()
andEnterStallCommand#execute()
returns aCommandResult
object to theLogicManger
.
Below is the activity diagram that summarizes what happens during the execution of the enter
command:
5.3.2. Enter Design Considerations
Aspect: Select command to be used instead of Enter
-
Alternative 1 (current choice):
enter
-
Pros:
enter
only handles the viewing of canteens and stalls. -
Cons: Might accidentally type
select
as theselect
command is also implemented in FoodieBot.
-
-
Alternative 2:
select
-
Pros: one command to select canteens, stalls and food items.
-
Cons: Additional checks for
select
command to detect if a food is chosen, so that it gets add into transactions.
-
5.4. Favorites Command
The favorites
command is implemented by the FavoritesCommand
class.
This command is accessed by the LogicManager#execute()
to edit or view the favorite on food items.
The following activity diagram illustrates what happens when a user executes the favorite
command:
5.4.1. Favorites Command Implementation
-
The
LogicManager
first executesFoodieBotParser
to create aFavoritesCommandParser
object. -
FavoritesCommandParser
then parse the user input to determine if the favorite command isset
,remove
, orview
. This process returns a newFavoritesCommand
object. -
The
LogicManager
then accessFavoritesCommand#execute()
. -
If
set
was chosen, the selected food item favorite is then updated. -
If
view
was chosen, a list of favorite food items are displayed. -
If
remove
was chosen, the respective food item is remove from the favorite food item list. -
FavoritesCommand#execute()
creates a newActionCommandResult
that extends theCommandResult
which is to be returned to theLogicManager
.
Below is the sequence diagram that summarizes what happens during the execution of the favorites
command:
5.4.2. Favorites Design Considerations
Aspect: favorites set
operates on stalls and food items
-
Alternative 1 (current choice):
favorites set
operate only for food items-
Pros: Only need to maintain one list of food items.
-
Cons: Does not allow stall to be added to favorites, the randomize feature cannot take into account of users' stall preferences.
-
-
Alternative 2:
favorites set
operate for both stalls and food items-
Pros: Can favorite a single stall rather than adding all the food items in the stall.
-
Cons: Cannot identify which food in particular the user likes from the stall. For instance, the user might not like spicy food and the stall sells a food item with that food characteristic.
-
5.5. Filter Command
The filter
command is implemented by the FilterCommand
class.
This command is accessed by the LogicManager#execute()
to filter outputs according to th euser input.
The following activity diagram illustrates what happens when a user executes the filter
command:
5.5.1. Filter Command Implementation
-
The
LogicManager
first executesFoodieBotParser
to create aFilterCommandParser
object. -
FilterCommandParser
then parse the filter command to determine if the filter output should be by price range or tags
This process returns a newFilterCommand
object. -
The
LogicManager
then accessFilterCommand#execute()
which filter the options based on the user input and the context wherefilter
is called. -
If the filter option is based on a price, the current context has to be the stall, otherwise an error message is thrown.
-
If the option is based on a tag, the filter option will return a list of option base on the current context.
-
FilterCommand#execute()
returns aCommandResult
to theLogicManager
.
Below is the sequence diagram that summarizes what happens during the execution of the filter
command:
5.5.2. Filter Design Considerations
Aspect: filter
allow partial name tag filters
-
Alternative 1 (current choice):
filter
is using strict match case.-
Pros: Can be accurate in the filter, for example, typing
filter ex
with not return both food that are expensive and or considered as extras in a combo set -
Cons: -
-
-
Alternative 2:
filter
allow partial name tag search.-
Pros: More lenient in tag search
-
Cons: Long list of filter results
-
5.6. Goto Command
The goto
command is implemented by the GoToCanteenCommand
class.
This command is accessed by the LogicManager#execute()
to display the direction to a canteen base on the user input.
The following activity diagram illustrates what happens when a user executes the goto
command:
5.6.1. Goto Command Implementation
-
The
LogicManager
first executesFoodieBotParser
to create aGoToCanteenCommandParser
object. -
GoToCanteenCommandParser
then parse the goto command to determine the canteen name and the current location.
This process returns a newGoToCanteenCommand
object. -
The
LogicManager
then accessGoToCanteenCommand#execute()
to retrieve the directions based on the user input. -
GoToCanteenCommand#execute()
creates a newDirectionsCommandResults
that extends theCommandResult
which is to be returned to theLogicManager
.
Below is the sequence diagram that summarizes what happens during the execution of the goto
command:
5.6.2. Goto Design Considerations
Aspect: Command format
-
Alternative 1 (current choice):
goto CANTEEN_INDEX f/CURRENT_LOCATION
-
Pros: Displays the directional instructions only for the current location to the canteen.
-
Cons: If no directions are found for the current location to canteen, the user has to try another location by changing it in the command box.
-
-
Alternative 2:
directions
shows directions categorised by blocks. For example,//example snippet Com1 1. To Nus Flavors: ... 2. To The Deck: ... . Utown 3. To Nus Flavors: ... 4. To The Deck: ... . //end of example
-
Pros: It is not required to enter any prefix or remember any block name.
-
Cons: Display a list of possible directional instructions of current locations to the canteen. One has to scroll down the list to find the correct list item to show the directions.
-
5.7. Randomize Command
The randomize
command is implemented by the RandomizeCommand
class.
This command is accessed by the LogicManager#execute()
to generate five random options based on the user input.
The following activity diagram illustrates the different scenario for the randomize command:
5.7.1. Randomize Command Implementation
-
The
LogicManager
first executesFoodieBotParser
to create aRandomizeCommandParser
object. -
RandomizeCommandParser
then parse the randomize command to separate the prefix if any and return a command object. In this case aRandomizeCommand
object is created and returned to theLogicManager
. -
The
LogicManager
then accessRandomizeCommand#execute()
. -
From
RandomizeCommand#execute()
,randomize
objects are called to generate a random option based on the user input. -
The
RandomizeCommand#execute()
returns aCommandResult
object to theLogicManger
.
Below is the sequence diagram that summarizes what happens during the execution of the randomize
command:
5.7.2. Randomize Design Considerations
Aspect: Context where randomize c/
can be called from
-
Alternative 1 (current choice):
randomize c/
function is only called from the canteen context.-
Pros: Only allow canteen index or name shown in the displayed list to be entered with the prefix.
-
Cons: Prefix is necessary to indicate that randomize works with one canteen only.
-
-
Alternative 2 :
randomize c/
can be called anywhere within FoodieBot.-
Pros: -
-
Cons: The index might not be bound to the canteen when index is used.
-
5.8. Rate Command
The rate
command is implemented by the RateCommand
class.
This command is accessed by the LogicManager#execute()
to rate a food item.
The following activity diagram illustrates what happens when a user executes the rate
command:
5.8.1. Rate Command Implementation
-
The
LogicManager
first executesFoodieBotParser
to create aRateCommandParser
object. -
RateCommandParser
then parse in the user input to ensure that therate
command is only use in the transaction context and that the inputs are valid.
This process creates and return aRateCommand
object to theLogicManager
. -
The
LogicManager
then access theRateCommand#execute()
to retrieve the food item from the transaction storage and update the rating of the food. -
The
RateCommand#execute()
returns aCommandResult
object to theLogicManger
.
Below is the sequence diagram that summarizes what happens during the execution of the rate
command:
5.8.2. Rate Design Considerations
Aspect: Rate command allows 0
-
Current choice: Rating starts from 1.
-
Pros: Does not cause confusion whether a rating of 0 means food item is not rated.
-
Cons: Cannot remove a rating by setting it to 0.
-
5.9. Review Command
The review
command is implemented by the ReviewCommand
class.
This command is accessed by the LogicManager#execute()
to review a food item.
The following activity diagram illustrates what happens when a user executes the review
command:
5.9.1. Review Command Implementation
-
The
LogicManager
first executesFoodieBotParser
to create aReviewCommandParser
object. -
ReviewCommandParser
then parse in the user input to ensure that thereview
command is only use in the transaction context and that the inputs are valid.
This process creates and return aReviewCommand
object to theLogicManager
. -
The
LogicManager
then access theReviewCommand#execute()
to retrieve the food item from the transaction storage and update the review of the food. -
The
ReviewCommand#execute()
returns aCommandResult
object to theLogicManger
.
Below is the sequence diagram that summarizes what happens during the execution of the review
command:
5.9.2. Review Design Considerations
Aspect: review
uses a separate screen
-
Alternative 1 (current choice):
review 1 this is a message
-
Pros: Able to update a review message conveniently
-
Cons: Review message may be too long which may not fit within the ui card
-
-
Alternative 2:
review INDEX
. FoodieBot shows review edit screen to type message.-
Pros: Remove the need to do any checking on prefixes
-
Cons: A valid command can be entered but not recognised. The user has to accept the change to navigate away. If the back command is accepted, the user can’t enter the single word
back
as the review message.
-
5.10. Report Command
The report
command is implemented by the ReportCommand
class.
This command is accessed by the LogicManager#execute()
to review a food item.
The following activity diagram illustrates what happens when a user executes the report
command:
5.10.1. Report Command Implementation
-
The
LogicManager
first executesFoodieBotParser
to create aReportCommandParser
object. -
ReportCommandParser
then parse an optional user input to determine the period of report to display.
This Process returns aReportCommand
object to theLogicManager
. -
The
LogicManager
then accessReportCommand#execute()
. -
The
ReportCommand#execute()
retrieves the transaction list from storage and display a list adapted to a report format within the given period, or all transactions if the period is not given. -
The
ReportCommand#execute()
returns aCommandResult
object to theLogicManger
.
Below is the sequence diagram that summarizes what happens during the execution of the report
command:
5.10.2. Report Design Considerations
Aspect: Functionality aspect of report
-
Alternative 1 (current choice):
report
-
Pros: Shows a generated report when the command is entered.
-
Cons: -
-
-
Alternative 2:
report
command to be combined withtransactions
-
Pros: A report can be generated right from transactions which means one less command to manage.
-
Cons: It is still required to type
report
aftertransactions
command is entered.
-
5.11. Select Command
The select
command is implemented by the SelectItemCommand
class.
This command is accessed by the LogicManager#execute()
to store the current selected food item into the storage as well as to update the current budget of the user.
The following activity diagram illustrates what happens when a user executes the select
command:
5.11.1. Select Command Implementation
-
The
LogicManager
first executesFoodieBotParser
to create aSelectItemCommandParser
object. -
SelectItemCommandParser
then parse the select command to ensure that the select command is called only on the stall context. This process also checks if the user input is the food index or the food name that is available in that stall. Returning aSelectItemCommand
object to theLogicManager
. -
The
LogicManager
then accessSelectItemCommand#execute()
. -
The
SelectItemCommand#execute()
retrieve the selectedFood
and creates aPurchasedFood
object with additional variables. -
The
SelectItemCommand#execute()
adds thePurchasedFood
to the existing transactions list for storage. -
The
SelectItemCommand#execute()
returns aCommandResult
object to theLogicManger
.
Below is the sequence diagram that summarizes what happens during the execution of the select
command:
5.11.2. Select Design Considerations
Aspect: How food items are selected
-
Current Choice: Selects the food item with
select INDEX
-
Pros: clean, easy to understand command syntax
-
Cons: may be confused and used interchangeably with
enter
-
5.12. Transactions Command
The transactions
command is implemented by the TransactionsCommand
class.
This command is accessed by the LogicManager#execute()
to display the transaction of the given period if stated.
The following activity diagram illustrates what happens when a user executes the transactions
command:
5.12.1. Transactions Command Implementation
-
The
LogicManager
first executesFoodieBotParser
to create aTransactionsCommandParser
object. -
TransactionsCommandParser
then parse an optional user input to determine the period of transaction report to display.
This Process returns aTransactionsCommand
object to theLogicManager
. -
The
LogicManager
then accessTransactionsCommand#execute()
. -
The
TransactionsCommand#execute()
retrieve the transaction list from storage and display the list within the given period, or all transactions if the period is not stated. -
The
TransactionsCommand#execute()
returns aCommandResult
object to theLogicManger
.
Below is the sequence diagram that summarizes what happens during the execution of the transactions
command:
5.12.2. Transactions Design Considerations
Aspect: transactions
should be included as a feature
-
Alternative 1 (current choice):
transactions
-
Pros: There is no need to worry about prefixes.
-
Cons: To review or rate a food item, it has to always start with the transactions command.
-
-
Alternative 2: The food item is reviewed after selecting the canteen and/or stall without having
transactions
command.-
Pros: Convenience in being able interact with the screen using multiple commands.
-
Cons: Ui may look cluttered. Increases difficulty to test.
-
6. Testing
Refer to the guide here.
7. Dev Ops
Refer to the guide here.
Appendix A: Product Scope
Target user profile:
-
has a need to keep track for food expenses
-
are indecisive on what food to have in campus
-
does not know which canteens are near them
-
is comfortable with command-line inputs on desktop
Value proposition: get a food choice decided without having to work with GUI controls
Appendix B: User Stories
|
Note
|
The user is not particularly limited to student and staff, it can be anyone who comes to visit NUS and is introduced to use the app |
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
| Priority | As a … | I want to … | So that I can… |
|---|---|---|---|
|
new user |
see usage instructions. |
refer to instructions when I forget how to use the App. |
|
user |
find nearest canteens. |
get to the canteen quickly. |
|
user |
see which stores are open. |
remove entries that I no longer need. |
|
user who is new to NUS (tourist, visitor or freshman). |
get a clear directory to the canteen |
make my way to the canteen with ease. |
|
user in campus |
randomize a food choice. |
try something new every now and then. |
|
user who is budget conscious |
know which food items fall within my budget. |
I would not overspend. |
|
user |
take down some personal notes about the store, for example which dish at the mixed veg store is good. |
see which is my favourite food amongst the NUS canteens. |
|
user who has an idea of what s/he wants to have |
search for food items. |
see which canteens sell them. |
|
user |
see which food items I have not tried. |
try all food items in the canteen. |
|
user with disability |
know if there is convenient access to the canteen. |
try all food items in the canteen. |
|
student on budget |
search through prices of food items in different canteens. |
discover which are the cheapest food items. |
|
user who do not carry a lot of cash |
see the type of payment methods available. |
prepare myself beforehand. |
|
user |
track the frequency of the food I eat. |
eat certain food in moderation and save money if i have been eating expensive food frequently. |
|
user |
see some images of the food . |
get some better understanding of the food aside from just the food description. |
|
user who is health conscious |
view the dietary options available for each canteen. |
know which stall i can visit. |
B.1. User Story for Version 2.0
| Priority | As a … | I want to … | So that I can… |
|---|---|---|---|
|
user |
place an order. |
receive the food when I arrive. |
|
store owner |
add new food items on the menu. |
easily update the menu. |
|
store owner |
set menu items to be on promotion. |
attract more students to select the menu item. |
|
user |
view the crowd condition. |
avoid going to the canteen if it is too crowded. |
|
user |
send invitation to a friend. |
have meals together with friends. |
Appendix C: Use Cases
(For all use cases below, the System is FoodieBot and the Actor is the user, unless specified otherwise)
Use case: UC1 - Select a randomised stall suggestion
MSS
-
User requests to randomise
-
FoodieBot shows the randomised suggestions
-
User selects one of the randomised suggestion
Use case ends.
Extensions
-
1a. User wants to remove a randomised suggestion.
-
1a1. User request to remove suggestion.
-
1a2. FoodieBot updates the food item not to be suggested in the future
Use case resumes at step 2.
-
Use case: UC2 - Set Budget
MSS
-
(Optional) User requests to view budget
-
FoodieBot shows the current budget with list of expenses
-
User request to set budget
-
FoodieBot updates the budget for the specified period
Use case ends.
Extensions
-
3a. The given amount is invalid.
-
3a1. FoodieBot shows an error message.
Use case resumes at step 2.
-
-
3b. The given period is invalid.
-
3b1. FoodieBot shows an error message.
Use case resumes at step 2.
-
Use case: UC3 - Review Food Item
MSS
-
User requests to view transactions
-
FoodieBot shows a list of transactions
-
User request to review the food item in the list
-
FoodieBot shows the edit screen for user to update
-
FoodieBot saves the user review
Use case ends.
Extensions
-
2a. The list is empty.
Use case ends.
-
3a. The given index is invalid.
-
3a1. FoodieBot shows an error message.
Use case resumes at step 2.
-
-
5. The cancel command is supplied.
Use case resumes at step 2.
Use case: UC4 - Rate Food Item
MSS
-
User requests to view transactions
-
FoodieBot shows a list of transactions
-
User request to rate the food item in the list
-
FoodieBot updates the review for the food item on the list
Use case ends.
Extensions
-
2a. The list is empty.
Use case ends.
-
3a. The given index is invalid.
-
3a1. FoodieBot shows an error message.
Use case resumes at step 2.
-
-
3b. The given rating is invalid.
-
3b1. FoodieBot shows an error message.
Use case resumes at step 2.
-
-
Fig1. Use Case Diagram
Appendix D: Non Functional Requirements
-
Should work on any mainstream OS as long as it has Java
11
or above installed. -
Should be able to hold up to 1000 food items without a noticeable sluggishness in performance for typical usage.
-
A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse.
-
Should be usable by users who have never used an e-directory
-
The application should have images for the food items, if the food items are shown to the user
-
The system should be backward compatible with data produced by earlier versions of the system
Appendix E: Glossary
- Activity Diagram
-
Use to a model workflow.
- API
-
Application Programming Interface
- CLI
-
Command Line Interface
- In-Memory
-
Type of database that relies primarily on memory for data storage.
- MSS
-
Main Success Scenario
- Mainstream OS
-
Windows, Linux, Unix, OS-X
- PlantUML
-
Component used to write diagrams.
- Sequence Diagram
-
Captures the interactions between multiple objects for a given scenario.
- UI
-
User Interface
Appendix F: Product Survey
Product Name Pizza on iOS appstore
Author: Bryan Wu
Pros:
-
Allow randomisation for food that requires choosing of ingredients
Cons:
-
Allow choosing of ingredients for pizza only
-
Does not recommend which stores sell the pizza


The slot/counter.h
header defines macros used generate numbers that are unique within a translation unit.
#include <chaos/preprocessor/slot/counter.h>
The CHAOS_PP_COUNTER
macro expands to the current counter value.
CHAOS_PP_COUNTER
This macro expands to an integer literal.
Its initial value defaults to 0
.
This initial value (per translation unit) can be overridden by defining CHAOS_PP_SEED
.
Each usage of CHAOS_PP_UPDATE_COUNTER
increases the current value by one.
Between usages of CHAOS_PP_UPDATE_COUNTER
, the value of CHAOS_PP_COUNTER
is constant.
#include<chaos/preprocessor/cat.h>
#include<chaos/preprocessor/slot/counter.h>
??=includeCHAOS_PP_UPDATE_COUNTER
() structCHAOS_PP_CAT
(register_,CHAOS_PP_COUNTER
) { inlineCHAOS_PP_CAT
(register_,CHAOS_PP_COUNTER
)(void) { return; } // ... }; ??=includeCHAOS_PP_UPDATE_COUNTER
() structCHAOS_PP_CAT
(register_,CHAOS_PP_COUNTER
) { inlineCHAOS_PP_CAT
(register_,CHAOS_PP_COUNTER
)(void) { return; } // ... };
The CHAOS_PP_COUNTER_ID
macro indirectly expands to CHAOS_PP_COUNTER
.
CHAOS_PP_COUNTER_ID
()
This macro effectively allows CHAOS_PP_COUNTER
to be passed around without expansion.
The CHAOS_PP_COUNTER_
macro expands to a λ expression representing CHAOS_PP_COUNTER
.
CHAOS_PP_COUNTER_
This macro is a shorthand form of the following λ binding:
The CHAOS_PP_UPDATE_COUNTER
macro increments the current counter value.
??=include CHAOS_PP_UPDATE_COUNTER
()
The CHAOS_PP_UPDATE_COUNTER_ID
macro indirectly expands to CHAOS_PP_UPDATE_COUNTER
.
CHAOS_PP_UPDATE_COUNTER_ID
()
This macro exists only for uniformity with other macros that require indirect invocation.
The CHAOS_PP_UPDATE_COUNTER_
macro expands to a λ expression representing CHAOS_PP_UPDATE_COUNTER
.
CHAOS_PP_UPDATE_COUNTER_
This macro is a shorthand form of the following λ binding:
The CHAOS_PP_SEED
macro defines the initial value (in a translation unit) of CHAOS_PP_COUNTER
.
#define CHAOS_PP_SEED
x
The integer literal to be used as the initial value of CHAOS_PP_COUNTER
.
If defined by the user, this macro must be defined prior to including any library headers.
If it is not defined by the user, it defaults to 0
.
This macro can be defined on the command line such that unique numbers can be generated across multiple translation units.


Seatte
- Hours Open : 6am - 7pm
- Contact Info :<PHONE_NUMBER>
- Location : 2901 3rd Ave#300 , Seatte WA98121
- Email<EMAIL_ADDRESS>Seattle is a seaport city on the West Coast, United. It is the county seat of King County in the Washington Post, the state's Pacific Northwest cities. According to the U.S. Census published in 2019, the city has 3.98 million inhabitants, which makes Seattle the fifth largest tide.
Tokyo
- Hours Open : 6am - 7pm
- Contact Info :<PHONE_NUMBER>
- Location : 1 Chome-1-2 Oshiage , Sumida City , Tokyo 131-8643
- Email<EMAIL_ADDRESS>The Japanese capital, the West Bank, the West Bank, the West Bank, from the Sumida River estuary. The capital of Japan since 1868 AD, is today the economic, economic, cultural and artistic center of the country.
Dubai
- Hours Open : 6am - 7pm
- Contact Info :<PHONE_NUMBER>
- Location : 1 Sheikh Mohammed bin Rashid Blvd-Dubai
- Email<EMAIL_ADDRESS>Dubai is a city and emirate in the United Arab Emirates, distinct and vibrant signatures. Burj Khalifa, at 830 m, is dominated by the skyline of skyscrapers. Below the tower is the Dubai Fountain with fountains and lights chime with the music. Atlantis, the Palm, a resort with water parks and marine life parks, sits on artificial islands in the opposite direction.
Paris
- Hours Open : 6am - 7pm
- Contact Info :<PHONE_NUMBER>
- Location : Champ de Mars , 5Zvenue Auatole France , 75007 Paris
- Email<EMAIL_ADDRESS>Paris is the capital and largest city of France by population. It is located on the banks of the Seine River in the northern part of the country in the heart of the Ile-de-France region. Its population reached 2,243,833 in 2010 within an administrative area only, while the population of the city and its suburbs exceeded 12 million people.
Lima
- Hours Open : 6am - 7pm
- Contact Info :<PHONE_NUMBER>
- Location : Ca.Gral.Borgono cuadra 8 , Miraflores
- Email<EMAIL_ADDRESS>Lima is the capital and largest city of the Republic of Peru. It is the cultural, economic and industrial center of the country and its transportation hub. The city lies between the rivers of Chillon, Rimak and Lorraine. With a population of close to 9 million, Lima is the fifth city in Latin America, after Manchester City, Sao Paulo, and Rio de Janeiro.


Circle of Catholic Women - Journals for personal reflection and ...
Circle of Catholic Women is a journal series tailored to Catholic women seeking deeper spiritual connections and life balance. . Through personal journaling and group sharing, you'll explore prayer, rituals and . having walked an open path .
http://www.circleofcatholicwomen.com/
Treatment for Herniated or Bulging Discs
The Temple in Time and Eternity - Temple Prayer in Ancient Times
24 These actions are reminiscent of a prayer circle. . Paul wrote that the woman's head should be covered during prayer (see 1 Corinthians . Prayer is also tied to the opening of the heavenly door in the Sermon on the Mount, in which Jesus .
http://maxwellinstitute.byu.edu/publications/books/?bookid=21&chapid=105
Feminine Divine
Centering Prayer for Women's Circle. Feminine Divine,. We know that when sisters gather together forming sacred circles,. the wind, breath, spirit blows . . . and .
http://globalwomensproject.files.wordpress.com/2011/02/centering-prayer-for-womens-circle.docx
opening prayer for womans circle Herniated or Bulging Discs
Peace Prayers - Sacred Women Chant - by Marie Summerwood ...
Sep 30, 2012 . I offer it for use in solitary work or in a circle of women. . women gather all over the world to sing and open to our own power, our own beauty, .
http://www.susunweed.com/Peace_Sacred_Women_Chant.htm
Prayer of the Day: Women's History Month - God's Politics Editor ...
Mar 8, 2011 . We remember that March is Women's History Month. Thank you for . Prayer of the Day: Women's History Month. by God's . The Circle of Life .
http://sojo.net/blogs/2011/03/08/prayer-day-womens-history-month
Women's Healing & Meditation Circle - Rainbow Dancer's Cloud
The Sacred Feminine women's circle offers safe and gentle space for women of all ages . During the circle, there is meditation for relaxation and opening of the . of Light held on alternate Tuesday nights and to the daily general prayer list.
http://www.rainbowdancerscloud.com/SpiritHeart/womens_healing.html
Official Impairment Listing for Spinal Disorders
The Prayer Thing: Why Women Aren't Worthy to Open Meetings Äî ...
Jun 18, 2007 . He said he had no problem with women giving the opening prayer. . she could train me) suggested that we stand in a circle and hold hands.
http://www.mormonmomma.com/index.php/2007/prayer-thing/
- laptop computer for for free (narrowing of the spine)
Stone Circle - Thank You
Each month lays out: a Theme, an Opening Prayer, Questions for Discussion, . to be a simple hands on guide to facilitating monthly women's circle gatherings.
http://www.stonecircleonline.org/store/store.htmCircle of Mysteries: The Women's Rosary Book - Christin Lore ...
A compelling, fresh look at the centuries-old prayer of the rosary. It gives new . Circle of Mysteries: The Woman's Rosary Book Including the Mysteries of Light .
http://books.google.com/books/about/Circle_of_Mysteries.html?id=c5MRy4QBLW4C
Events - Women's Interfaith Network Foundation
Called Sharing Our Wisdom, the event was a gathering of women from a multitude . We sat in a large circle and shared opening prayers by representatives of .
http://www.winfoundation.net/events.html
Worship Ideas for Women | eHow.com
Pray or meditate alone in your garden or with a group of women. Practice your . Come to your altar with an open mind and heart. Sit before it . If you belong to a religious organization, invite members to your home for prayer circles. Women of .
http://www.ehow.com/info_8356802_worship-ideas-women.html
Medical-Vocational Allowance for Herniated Disc
Prayers for women
Talk in CIRCLES · Get our newsletter . Can we, as women, risk listening to God who may seem to ask the impossible? . Prayer for Guidance; Meditations for encouragement; You keep us waiting . If you have been opened by life's betrayals .
http://www.womenpriests.org/prayer/prayers1.asp
Praying hands Stock Photos and Images. 9101 praying hands ...
Two hands open in prayer . Young women sitting with eyes closed and hands in prayer position ... Photo Alto . Close up of woman's hands folded in prayer .
http://www.fotosearch.com/photos-images/praying-hands.html
Appealing a Denial of Benefits
Women's Prayer Group Praying That the Women at MRFF All Get ...
Apr 24, 2012 . A women's prayer group is praying that all the women at MRFF get incurable . Our prayer circle has never failed to acheive our hosts granting of the . My eyes are opened everyday which is why I hang out here at FTB.
http://freethoughtblogs.com/rodda/2012/04/24/womens-prayer-group-praying-that-the-women-at-mrff-all-get-incurable-breast-cancer/


I have just setup a new system having received all the bits needed yesterday.
EmonTX V3 ready built with one CT sensor
Raspberry Pi running EMonCMS with hard disc
I haven't built up the EmonGLCD yet and I am running the EmonTX from pen cell batteries at the moment. The 9V AC transformer still has to be connected.
I have been running a Current Cost setup until now and thought it was fairly accurate, possibly reading a bit high. The reading I am getting from the Emon setup seems very high. At the moment it's showing 1212Watt and the Current Cost is showing 920Watt. Thats nearly 300 watt difference. Checking the actual amount consumed over an hour on the household meter it's more or less agreeing with the Current Cost reading. I am wondering if I have missed something in the setting up process. I know I haven't got the 9V AC power connected yet, but neither has the Current Cost unit. Any suggestions?
Re: Accuracy question
The emonTx V3 sketch assumes a system voltage of 230 V if it can't see an ac input. As you appear to be in the UK, your nominal system voltage is still likely to be 240 V, so that immediately accounts for an error of 4% or so but in the wrong direction. You're 30% adrift. The c.t. itself has a 3% tolerance, and the burden resistor 1%, and the analogue reference a further 2%. So you should be within 6%. Can you check the 3.3 V rail on your emonTx? That is also the reference for the ADC and if that is low, then the current measurements will be correspondingly high. I assume you are using the shop c.t. in CT1.
What load did you have? Without the voltage reference, the emonTx can only measure current and hence show an apparent power, with assumptions about the voltage, as I've mentioned, and the power factor. If the power factor of your load is particularly bad (it would have to be about 0.7) that would go a long way towards explaining the difference (except we don't know what the CurrentCost unit's assumptions are).
Re: Accuracy question
Thank's for the pointers. I am going to connect up the AC adapter tomorrow as I am think that the error may be due to voltage changes. I am still getting to grips with the system and really need to do some more definitive tests. One thought. I have the CT which incidentally is the shop one, on the live line and the Current Cost CT is on the neutral line. Both CT's are fairly close to each other. Is it possible for them to have some form of crosstalk and interfere with each other.
So the the only test was to watch the house meter consumption over an hour with what looked like a fairly constant load of about 1kW. It was then that I noticed the big discrepancy. However since then (a few hours later) both were showing the same reading. So I am even more confused at the moment.
What I would like to do is run for a day and make a note of the consumption on the house meter and find a way to compare it with the Emoncms readings. But at the moment I dont understand the system enough to do consumption measurement over a fixed period of time.
Re: Accuracy question
I don't think an error that big is down to one cause, but several all adding up the wrong way.
Until you get the voltage input working, the emonTx and the electricity company's meter are measuring different quantities, one real power/energy, the other apparent power; so unless all your loads are purely resistive, they should never agree since apparent power must always be the same or larger than real power.
The c.t's might well interact, but only to a very small degree because all the flux should be trapped inside the core, and very little should leak out. I've never tried to make any definitive measurements but I've also never noticed an effect - and I've had three on the same cable with only an inch or so between them.
If you look into what you can do with emonCMS, you'll see that kWh features fairly prominently, so you should be able to do a direct comparison, when you have the voltage input working that is.


Alerts
Well Done !
You have successfully used the bootstrap alert component
This is my danger text
This is my info text
Badges
Breadcrumbs


Fun with Unicode! 2007/12/01
Why can't XULRunner do this already?
Without really saying what "this" is, Mozilla wants XULRunner to be the standard play for cross-platform GUI applications and yet it has a bit of trouble interacting with 3rd party libraries. Most mature libraries (say, GraphicsMagick) still use char *
or std::string
to represent file paths. To interact with them, then, you have to be able to get to a char *
representation of files you're trying to open.
Windows and Mac character encodings 101
As is becoming tradition, Windows makes my life difficult by using UTF-16 as its Unicode of choice. UTF-16 uses 2 bytes (usually) to represent each character, meaning it isn't binary compatible with ASCII, which uses 1 byte per character. These 2-byte characters are stored in wchar_t
s which are twice as wide as char
s. It isn't possible to pass a wchar_t *
through normal C libraries that expect strings as char *
.
Mac OS X uses UTF-8 internally and is my hero. UTF-8 is used internally to represent strings and has the advantage of using single bytes (that's char
for C programmers playing along) as its base unit. While a single character in UTF-8 can span up to 8 bytes, the in-memory representation of these characters will pass muster with a C compiler. When the UTF-8 bytes are passed through some C library they can arrive intact to the fopen
system call, which understands the UTF-8 bytes and acts like you'd expect.
There's an easy way?
There could be. Using the @mozilla.org/file/local;1
it might be possible to get the path as an nsACString
, Mozilla's portable representation of single-byte ASCII strings. But, the reference warns that the native path available from nsILocalFile is not for passing to C libraries and isn't guaranteed to be correct. So it's up to me.
No pain, no gain
Bear with me, this gets ugly. The solution that lets me take paths from JavaScript-land to C-land, open Unicode paths with a normal char *
and do so on Windows and Mac OS X is stupefying (and stupid). The iinitial path is stored as a JavaScript string, so the boundary between JavaScript and C will be an nsAString
, which represents strings as UTF-16.
The string takes quite a journey here, so let's cover the easy side first. Macs understand UTF-8, and I'm making a transformation to UTF-8 in JavaScript. This means that the only transform needed in C is a type change, not an encoding change. The UTF-8 string enters C-land as wide characters and is simply cast character-by-character down to an array of bytes.
Windows is quite a bit more work, since a path in Windows that needs Unicode characters can't easily be represented as a char *
. Enter the Windows API function GetShortPathName
. This can convert any path to an old-school Windows path that fits in ASCII and uses that familiar "8.3" naming convention. I got the Mac half working first, so the Windows implementation is actually more complicated than it needs to be -- more on that later. Without further ado:
string * conv_path(const nsAString & fake) { // Fun with Windows paths #ifdef XP_WIN // UTF-16 but really UTF-8 nsAString to really UTF-8 nsCString nsCString utf8 = NS_LossyConvertUTF16toASCII(fake); // UTF-8 nsCString to UTF-16 nsEmbedString nsEmbedString & utf16 = NS_ConvertUTF8toUTF16(utf8); // UTF-16 nsEmbedString to wchar_t[] wchar_t * w_arr = new wchar_t[utf16.Length() + 1]; if (0 == w_arr) return 0; wchar_t * w_arr_p = w_arr; PRUnichar * w_start = (PRUnichar *)utf16.BeginReading(); const PRUnichar * w_end = (PRUnichar *)utf16.EndReading(); while (w_start ! w_end) { *w_arr_p++ = (wchar_t)*w_start++; } *w_arr_p = 0; // GetShortPathName to get guaranteed ASCII wchar_t s_arr[4096]; if (0 == GetShortPathNameW(w_arr, s_arr, 4096)) { delete [] w_arr; return 0; } delete [] w_arr; // wchar_t[] to ASCII nsEmbedString nsEmbedString ascii; wchar_t * s_arr_p = s_arr; while (*s_arr_p) { ascii.Append((char)*s_arr_p++); } // Macs don't need any help since they understand UTF-8 #else nsEmbedString ascii; ascii.Assign(fake); #endif // Convert the nsEmbedString into a std::string char * c_arr = c_arr = new char[ascii.Length() + 1]; if (0 == c_arr) return 0; char * c_arr_p = c_arr; PRUnichar * c_start = (PRUnichar *)ascii.BeginReading(); const PRUnichar * c_end = (PRUnichar *)ascii.EndReading(); while (c_start ! c_end) { *c_arr_p++ = (char)*c_start++; } *c_arr_p = 0; string * str = new string(c_arr); delete [] c_arr; return str; }
This works simply because, on either platform, the result is a char *
that actually uniquely represents the desired file.
My code sucks, let me count the ways
There are of course things that could be better. First of all, after reading the code again (I wrote it Thursday and haven't looked back), I see that I should refactor a bit. By leaving the string in UTF-16 representation for passing to C-land, I can add a transform from UTF-16 to UTF-8 to the Mac version and greatly simplify the Windows version. I'll put that on my to-do list. The other place I hope to improve is in the event that GetShortPathName
fails. In this case, copying the file under a new ASCII filename to a temporary directory (found using GetTempPath
) would still let the file be accessed with a char *
path.
Why did I have to do this?
It would be sweeeeeet if Mozilla integrated this code (after a healthy dose of optimization) into the toolkit as something like NS_ConvertToNativePath(nsAString)
or some such function. Having this will make integrating with third-party libraries much easier.
Comments (7)
Yikes.. You are a beast for working through this.
— Mike Panchenko — 2007/12/01 10:55 am
The reason we don't do this is that GetShortPathName can fail, and has, if users have NtfsDisable8dot3NameCreation in their registry, or if they are mapping another filesystem (such as NFS) that doesn't have a concept of shortnames: see e.g. https://bugzilla.mozilla.org/show_bug.cgi?id=303598
— Benjamin Smedberg — 2007/12/01 7:11 pm
Ah, which is why I still need to back all this up with a copy to the TMP directory. I still think there might be a good reason to have this function if just to avoid unnecessary file copying. It isn't foolproof but it is a good shortcut to take when you can.
— Richard Crowley — 2007/12/02 9:36 am
what happens if you do an opendir/readdir (or whatever the windows api equivalent versions are) on a folder with unicode named files in, using the non-unicode windows api (the A functions) wih 8.3 disabled? do the files appear at all? if they do, presumably the filenames given back are able to be passed to fopen, etc. hmm
— cal — 2007/12/02 1:13 pm
bah. the answer is that these files are unopenable. nice work windows :(
— cal — 2007/12/03 11:09 am
I don't know what all this means, but it makes me want to play with XUL.
— Andrew Mager — 2007/12/25 2:29 pm
well.. utf8 is so convenient, that's true, but it's also a major source of bugs in the software industry. Many developers do the confusion: they see a char* and consider it's ASCII. They perform then some manipulation on the string using the usual functions, the most disastrous being probably strrchr() that will often break some Asian compounds on utf8 strings, while it virtually never happens with utf16 strings with the equivalent wcsrchr(). So, there's no black and white. people tend to say that "Apple is cool and Microsoft sucks" but they actually have both advantages. To use UTF16 in Windows was a good idea since they defined wchar_t to two bytes. This means you can easily and safely (I would actually say 'almost safely') manipulate Unicode strings natively, meaning you have them readable in your favorite debugger, thanks to the ANSI C string functions (wscpy, etc). On the Mac, they decided for some obscure reasons to define the size of wchar_t to 4 bytes. This means the ws functions handle UTF32 that nobody likes to use, and make 50% of the C string functions useless. Most multi platform applications used UTF16 because it was safe and until now, supported almost everywhere. Now, developers have to make conversions from UTF16 to UTF8 and/or UTF32 while there is no functions on Mac OS X to help. UTF16 is not supported -from what I know, and I can do mistakes- so developers use all kinds of tricks to convert their UTF16 strings to something else.. and bugs happen on the Mac only. So, was it really a judicious choice?
As we can see, there is not a 'cool Apple' and a 'bad Microsoft'. They both have pros and cons. An application that could be compiled for Windows 95 still compiles for Vista, sizes haven't changed and everything runs smoothly; while we have to run after Apple's caprices each time they change their architecture, libraries, frameworks... But on the other hand, we must admit that to rewrite code is good, so I wouldn't say that 'Apple sucks' and 'Microsoft is good' ;-)
But finally, all this comes from a lack of string management in native c/c++ libraries. We can hope that Boost extensions will make our life better, and give a end to these too often useless discussions.
— Luc Leroy — 2008/05/07 8:40 am


This examples enhances an image with low contrast, using a method called histogram equalization, which “spreads out the most frequent intensity values” in an image [1]. The equalized image has a roughly linear cumulative distribution function.
While histogram equalization has the advantage that it requires no parameters, it sometimes yields unnatural looking images. An alternative method is contrast stretching, where the image is rescaled to include all intensities that fall within the 2nd and 98th percentiles [2].
| [1] | http://en.wikipedia.org/wiki/Histogram_equalization |
| [2] | http://homepages.inf.ed.ac.uk/rbf/HIPR2/stretch.htm |
import matplotlib.pyplot as plt
import numpy as np
from skimage import data, img_as_float
from skimage import exposure
def plot_img_and_hist(img, axes, bins=256):
"""Plot an image along with its histogram and cumulative histogram.
"""
img = img_as_float(img)
ax_img, ax_hist = axes
ax_cdf = ax_hist.twinx()
# Display image
ax_img.imshow(img, cmap=plt.cm.gray)
ax_img.set_axis_off()
# Display histogram
ax_hist.hist(img.ravel(), bins=bins, histtype='step', color='black')
ax_hist.ticklabel_format(axis='y', style='scientific', scilimits=(0, 0))
ax_hist.set_xlabel('Pixel intensity')
ax_hist.set_xlim(0, 1)
ax_hist.set_yticks([])
# Display cumulative distribution
img_cdf, bins = exposure.cumulative_distribution(img, bins)
ax_cdf.plot(bins, img_cdf, 'r')
ax_cdf.set_yticks([])
return ax_img, ax_hist, ax_cdf
# Load an example image
img = data.moon()
# Contrast stretching
p2 = np.percentile(img, 2)
p98 = np.percentile(img, 98)
img_rescale = exposure.rescale_intensity(img, in_range=(p2, p98))
# Equalization
img_eq = exposure.equalize_hist(img)
# Adaptive Equalization
img_adapteq = exposure.equalize_adapthist(img, clip_limit=0.03)
# Display results
f, axes = plt.subplots(2, 4, figsize=(8, 4))
ax_img, ax_hist, ax_cdf = plot_img_and_hist(img, axes[:, 0])
ax_img.set_title('Low contrast image')
y_min, y_max = ax_hist.get_ylim()
ax_hist.set_ylabel('Number of pixels')
ax_hist.set_yticks(np.linspace(0, y_max, 5))
ax_img, ax_hist, ax_cdf = plot_img_and_hist(img_rescale, axes[:, 1])
ax_img.set_title('Contrast stretching')
ax_img, ax_hist, ax_cdf = plot_img_and_hist(img_eq, axes[:, 2])
ax_img.set_title('Histogram equalization')
ax_img, ax_hist, ax_cdf = plot_img_and_hist(img_adapteq, axes[:, 3])
ax_img.set_title('Adaptive equalization')
ax_cdf.set_ylabel('Fraction of total intensity')
ax_cdf.set_yticks(np.linspace(0, 1, 5))
# prevent overlap of y-axis labels
plt.subplots_adjust(wspace=0.4)
plt.show()
Python source code: download (generated using skimage 0.9.0)


Eclipse Phase Tools
Home
|
About
|
Contact
Eclipse Phase GM Tools
New Characters
Aptitudes
Initiative
Combat Skills
Cookie Testing
New Characters
Add Character to List
Save List
Select the file to load
Enter Name
0
Add Character
Aptitudes
Initiative
Calculate Initiative
Generate Random Initiative
Next Character
Next Turn
Combat Skills
Character List
Fray
0
Save Cookie
Show Cookie
Load Cookie


{% load wagtailcore_tags wagtailimages_tags %} {# Individual event item in a list - used on event index and home page #}


How to find a Galarian Farfetch'd and evolve it to a Sirfetch'd!
Source: iMore
If you've been dying to get your hands on a Farfetch'd for the Galar region, you may have noticed it can be a little tricky to find one. What's more, evolving a Farfetch'd into the awesome sword-and-shield-wielding Sirfetch'd take a bit of knowledge and luck.
While you can only find a Galarian Farfetch'd in Pokémon Sword, you can always get the Pokémon via trade in Pokémon Shield as well. Here's where you can find a Galarian Farfetch'd and how to evolve it into a Sirfetch'd!
Where to find a Galarian Farfetch'd in Pokémon Sword
The Galar version of Farfetch'd will only pop up in two places in the wild in Pokémon Sword and the spawn rates are pretty low, so if you want to catch one, you'll likely need to search for a while to get the chance to catch one.
The easiest place to get one is on Route 5, which is the road that leads out of Turffield (pictured below on the left), and I had the most success finding Farfetch'd in the patches of grass by the pond (pictured below to the right). You should be able to find a Galarian Farfetch'd anywhere n Route 5; however, remember that the spawn rate is pretty low. The good news is if one does spawn, you'll always see it walking around the map, it won't spawn as a random encounter.
Source: iMore
This isn't the only place you can find a Farfetch'd in Galar, you can also find one in the Giant's Mirror area inside the Wild Area (pictured below); however, Pokémon found there will be a pretty high level, so you likely won't be able to catch one in the Giant's Mirror for quite some time.
Source: iMore
How to evolve a Galarian Farfetch'd into a Sirfetch'd in Pokémon Sword and Shield
Source: iMore
Unlike other Pokémon that need to reach a certain level, use an item, or be traded to evolve, the Galar region Farfetch'd is a Fighting-type Pokémon that prides itself on its battle skills. The only way a Farfetch'd will evolve to a Sirfetch'd is if Farfetch'd lands three critical hits in one battle.
After doing so, you'll get the prompted that your Farfetch'd is evolving and be a proud owner of a Sirfetch'd.
A couple of tips
Landing three critical hits in one battle can be a little tricky, and while there's no foold proof way to do it, here's a couple of quick tips you can use to give yourself a better chance.
Battle a trainer with multiple Pokémon
The chances of you being able to get three critical hits against a random Pokémon in the wild are pretty slim. Battle a trainer with multiple Pokémon and keep attacking with Farfetch'd to give yourself the best shot.
Teach Farfetch'd Focus Energy using TR13
Focus Energy is a move you can teach certain Pokémon, which increases the likelihood of landing critical hits. The good news is you can grab TR13, which contains Focus Energy, pretty early on.
If you talk to the guy who runs the record store in Motostoke (pictured below), he will give you TR 13 for free!
Source: iMore
Just remember that a TR can only be used once, so if you do use it to teach Focus Energy to your Farfetch'd, you won't be able to teach it to another Pokémon.
Any Questions?
Anything else you want to know about catch Farfetch'd and getting a Sirfetch'd on your team? Let us know in the comments below.


{% extends 'base.html' %} {% block title %}Previsualizacion jugadores{% endblock %} {% block content %} {% for deportista in deportistas %}
Contacto
Here is some more information about this product that is only revealed once clicked on.


previous
|
next
Front:
Back:
Website:
Category:
Update Flashcard
Delete Flashcard
Manage Categories
You have not yet created any flashcards.
test


Please follow each step completely. Use the other lessons and resources (Mozilla Developer Network) to help you. You may also get help from your classmates. Kevin and Adam will be able to help, so if you get stuck, raise your hand to let them know.
Our goal for this module is to reveal our Pokémon as tiles are clicked. We will not implement the rules of Memory yet (i.e., we will not check for matches or hide non-matching Pokémon yet).
The first thing we need to do is to create a click handler for all of the tiles. Below is a hint on how to create the click handler:
Inside the onClickTile
function, we will use the jQuery
.addClass()
method to add a few CSS classes to the tile that
was just clicked.
This is also where we will start using the Pokémon name that we
stored using jQuery's .data()
method earlier. We will use that
Pokémon name as a CSS class, which will help us show the
Pokémon on the tile.
First let's get the Pokémon name for the tile in question:
Then we need to add a few CSS classes to the tile:
The Pokémon name helps us know which Pokémon image to show on
the tile. The "revealed"
class is used to tell the browser to
show the Pokémon.


Jumpcut is subject to the MIT License. Source code and license details are available on the application's GitHub page.
Jumpcut is open source code built with open source code. Jumpcut incorporates the following libraries, used with gratitude:
Thanks to Clare Bates Congdon, Joshua Davis, Brad Graham, David Jacobs, John Kenzie, Adam Rice, Finn Smith, Vera Tobin, and Andre Torrez for early and ongoing feedback, advice, and encouragement.
Icon by John Kenzie.
Copyright © 2022 Steve Cook.


What is the English equivalent of the following Java-style boolean
expression?
!bob.hasFlower() && bob.isFacing(WEST)
Bob doesn't have a flower and is facing
west.
- Bob doesn't have a flower or he is facing west.
- Bob has a flower or he is not facing west.
- Bob has a flower and is facing west.
There are not hints for this question


Consignment Form Personal Information: First name: Last Name: Email: Shoe Information: Shoe Brand: Shoe Model:


~ By Ankit Kumar Gupta
|
Home
|
About
|
WELCOME TO MY PERSONAL BLOGGING PAGE
Featured Articles
Introduction to Java.
Author Name - Ankit Kumar Gupta
September 2, 2020 | 3 min read
SQL and its basic commands.
Author Name - Ankit Kumar Gupta
February 21 | 4 min read
Physical fitness is the first requisite of happiness - Joseph Pilates.
Author Name - Ankit Kumar Gupta
November 26, 2020 | 4 min read
MongoDB features.(~ Why MongoDB?)
Author Name - Ankit Kumar Gupta
September 21, 2020 | 4 min read
MongoDB: the choice for all database requirements.
Author Name - Ankit Kumar Gupta
September 13, 2020 | 5 min read
Eclipse: a boon IDE.
Author Name - Ankit Kumar Gupta
September 5, 2020 | 4 min read
Physical fitness is the first requisite of happiness - Joseph Pilates.
Author Name - Ankit Kumar Gupta
November 26, 2020 | 4 min read
Introduction to Java.
Author Name - Ankit Kumar Gupta
September 2, 2020 | 3 min read


Generalized linear models used to investigate the influence of management history (Man.H), functional diversity (Fdis), forest structure (subplot basal area and tree density), and the community‐weighted means of tree height, SLA, leaf size, wood density (Trait CWM). The three top models (those with the smallest AICc and whose ΔAICc ≤ 2) are in italics, while the best model is in bold letters. The best model was the simples of the top models


CHAPTER 244
LIQUOR TAX LAW
REPEALED. L Sp 1984 1st, c 1, §5.
Cross References
For present provisions, see chapter 244D.


FileSaver Sample
Click here
to download the "The Charge of the Light Brigade" by Alfred Lord Tennyson.


Cover
Music
Artist
Album
Year
Genre
Player
{{music.title}}
{{music.artist[0]}}
{{music.year}}
{{music.album}}
{{music.genre[0]}}


False Perceptions
问题描述 :
You have been reading Harry Potter series for some time. Since the final book will not be out in the store until 2007, and you are curious about what could happen in the final book of the series, you have decided to do some guessing by yourself. After rereading the series for some days, you have divided every piece of information you currently have into three categories:
A.
Extracts. Extracts are taken from the previous published books in the series, and you don’t need to check for their validities;
B.
Assumptions. Assumptions are based on different interpretations of other assumptions / extracts from the books. An assumption is plausible if and only if some of the assumptions (or extracts from the book) this assumption relies on are interpreted in ways that support this assumption. No assumption requires itself to be plausible, whether directly or indirectly.
C.
Theories. Theories are based on extracts and assumptions. If all the extracts and assumptions one theory depends on are believable and interpreted to support this theory, then we say this theory can be argued as believable.
Note that extracts and assumptions may have many different exclusive explanations leading to other theories and/or assumptions.
Because of personal preferences, you want to see some scenes in the next book come true much more than the others, thus you have assigned different values to different theories, each being an exponent of 2, less or equal to 2(number of theories-1) . You want to know what the maximal possible value of theories that can be argued as believable at the same time is; furthermore, since the less guesswork you do, the more reliable your theories are, you are interested in the minimum number of explanations you must make to make all those theories acceptable. Can you accomplish this seemingly impossible task?
输入:
Each test case starts with three integers N , M and K (1<=N<=1000, 1<=M<=5000, 1<=K<=100) , the number of extracts from the book, the number of assumptions and the number of theories, respectively.
The following part describes extracts and assumptions. Extracts are always described before assumptions. Each description starts with one string S , the name of the extract / assumption, and an integer T in the next line, the number of different explanations you have come up with; T lines follow, on each line there is a string X , the explanation which leads to another assumption / theory.
The next part of test case consists of K descriptions of theories. Each description starts with one string S , the name of the theory, followed by one integer P , the value which you have assigned to this theory.
Two successive descriptions are separated by a line with one single character `-’. It is guaranteed that the total numbers of explanations which extracts and assumptions have does not exceed 50000, and you may assume every string’s length is less or equal to 20, and only consists of letters from alphabet and numbers 0…9 .
N = 0 , M = 0 , K = 0 indicates the end of input file and should not be processed by your program.
输出:
Each test case starts with three integers N , M and K (1<=N<=1000, 1<=M<=5000, 1<=K<=100) , the number of extracts from the book, the number of assumptions and the number of theories, respectively.
The following part describes extracts and assumptions. Extracts are always described before assumptions. Each description starts with one string S , the name of the extract / assumption, and an integer T in the next line, the number of different explanations you have come up with; T lines follow, on each line there is a string X , the explanation which leads to another assumption / theory.
The next part of test case consists of K descriptions of theories. Each description starts with one string S , the name of the theory, followed by one integer P , the value which you have assigned to this theory.
Two successive descriptions are separated by a line with one single character `-’. It is guaranteed that the total numbers of explanations which extracts and assumptions have does not exceed 50000, and you may assume every string’s length is less or equal to 20, and only consists of letters from alphabet and numbers 0…9 .
N = 0 , M = 0 , K = 0 indicates the end of input file and should not be processed by your program.
样例输入:
2 3 1 Extract1 2 Assumption1 Assumption2 - Extract2 2 Assumption2 Assumption3 - Assumption1 2 Assumption2 Theory1 - Assumption2 0 - Assumption3 1 Theory1 - Theory1 1 0 0 0
样例输出:
Case 1: 1 4 Theory1
这都是因为任务需要。并不是飞行员不爱。
这都是因为任务需要。并不是飞行员不爱。
这都是因为任务需要。并不是飞行员不爱。
这都是因为任务需要。并不是飞行员不爱。
这都是因为任务需要。并不是飞行员不爱。
这都是因为任务需要。并不是飞行员不爱。
这都是因为任务需要。并不是飞行员不爱。
这都是因为任务需要。并不是飞行员不爱。
这都是因为任务需要。并不是飞行员不爱。
这都是因为任务需要。并不是飞行员不爱。
这都是因为任务需要。并不是飞行员不爱。
正是我要找的，适合新手
居然是机试，还和13年重复。题目不难
如何解决overload的问题呢？
为什么暴力求解方法循环到sqrt(n) 就可以了呢
正在学习搜索，很好
题本身没错，但是HDOJ放题目的时候，前面有个题目解释了什么是XXX定律。
这里直接放了这个题目，肯定没几个人明白是干啥
这个问题应该是有一般性的解决方法
这是什么编译器啊，不通过
很有意思，可惜我很菜啊
好的，多谢指出
这是什么编译器啊，不通过
博主的C++功底真是好
有没有C++语言的代码？


{% extends "/layout.html" %} {% block styles %} {% endblock %} {% block body %}
The ReCode Project is a community-driven effort to preserve computer art by translating it into a modern programming language (Processing). Every translated work will be available to the public to learn from, share, and build on.
The project's main goals are:
Scroll down to browse the collection. To participate, start by reading our USER GUIDE.
Day for Night Festival - The School for Poetic Computation has invited Recode Project to collaborate on an interactive installation at the Day for Night Festival. Anyone can submit their translation for consideration to be featured on a large screen for the duration of the event. Details can be found on the Github Wiki for the project. Works can be coded in Processing or openFrameworks.
"Computer Graphics and Art" was a quarterly magazine published between 1976 and 1978. We are using PDF copies of the entire run of the magazine as our starting point for the project. The majority of the artworks have no code published alongside the original result, providing an opportunity for a variety of interpretations and approaches, all of which can become the starting point for a new work.
PDFs of the original source documents come from compart via Rhizome.
Vol.1 No.1 (unavailable)


Related JIRA Ticket: SOHO-6448. Prior to version 4.3.1, in cases where the initialization component of the Soho library isn't used, Searchfield components were not aware of their existence inside of a toolbar parent. When used inside of a Toolbar, a searchfield should be invoked as a Toolbar Searchfield instead of a normal Searchfield. This test demonstrates functionality added to the regular Searchfield component that allows it to detect a toolbar parent, and pre-emptively invoke itself as a Toolbar Searchfield instead.
When this test completes, use a developer tools console and run this code: $('#test-searchfield').data('toolbarsearchfield'); - it should return an instance of a ToolbarSearchfield and not be undefined.


Core_CSS contains widget for handling touch and swipe. This widget based on TouchSwipe from Matt Bryson.
Widget can be used on touch devices such as iPad, iPhone, Android etc. Detects single and multiple finger swipes, pinches and falls back to mouse 'drags' on the desktop. Time and distance thresholds can be set to distinguish between swipe gesture and slow drag. Allows exclusion of child elements (interactive elements) as well allowing page scrolling or page zooming depending on configuration.
Widget features:
$(function() { $("#test").touch( { swipe:function(event, direction, distance, duration, fingerCount, fingerData) { $(this).text("You swiped " + direction ); } }); });
| Option | Data-* | Default | Description |
|---|---|---|---|
| fingers | data-fingers | 1 | Constants representing the number of fingers used in a swipe. |
| threshold | data-threshold | 75 | By setting the threshold you can set how far the user must swipe before it is considered a swipe. |
| cancelThreshold | data-cancel-threshold | null | |
| pinchThreshold | data-pinch-threshold | 20 | |
| maxTimeThreshold | data-max-time-threshold | null | |
| fingerReleaseThreshold | data-finger-release-threshold | 250 | |
| longTapThreshold | data-long-tap-threshold | 500 | |
| doubleTapThreshold | data-double-tap-threshold | 200 | |
| swipe | data-swipe | null | Function. Params: event, direction, distance, duration, fingerCount, fingerData, currentDirection |
| swipeLeft | data-swipe-left | null | Function. Params: event, direction, distance, duration, fingerCount, fingerData, currentDirection |
| swipeRight | data-swipe-right | null | Function. Params: event, direction, distance, duration, fingerCount, fingerData, currentDirection |
| swipeUp | data-swipe-up | null | Function. Params: event, direction, distance, duration, fingerCount, fingerData, currentDirection |
| swipeDown | data-swipe-down | null | Function. Params: event, direction, distance, duration, fingerCount, fingerData, currentDirection |
| swipeStatus | data-swipe-status | null | Function. Params: event, phase, direction, distance, duration, fingerCount, fingerData, currentDirection |
| pinchIn | data-pinch-in | null | Function. Params: event, direction, distance, duration, fingerCount, zoom, fingerData |
| pinchOut | data-pinch-out | null | Function. Params: event, direction, distance, duration, fingerCount, zoom, fingerData |
| pinchStatus | data-pinch-status | null | Function. Params: event, direction, distance, duration, fingerCount, zoom, fingerData |
| tap | data-tap | null | Function. Params: event, target |
| doubleTap | data-double-tap | null | Function. Params: event, target |
| longTap | data-long-tap | null | Function. Params: event, target |
| hold | data-hold | null | Function. Params: event, target |
| triggerOnTouchEnd | data-trigger-on-touch-end | true | With triggerOnTouchEnd you can trigger the swipe end handler either when the user releases (default) or when the user has swiped the distance / time of the thresholds (but is still swiping). |
| triggerOnTouchLeave | data-trigger-on-touch-leave | false | With triggerOnTouchLeave you can end the event if the user swipes off the element |
| allowPageScroll | data-allow-page-scroll | auto | Allow or disallow page scroll |
| fallbackToMouseEvents | data-fallback-to-mouse-events | true | Generate fallback to mouse events |
| excludedElements | data-excluded-elements | .noSwipe | If you want to exclude certain child elements from triggering swipes, you can simply add a .noSwipe class to the element. Then the element and any of its children will no longer trigger the swipe. Also, a jQuery selector is used to exclude input elements as well as the .noSwipe elements. By default all button, input, select, textarea and a elements are excluded. So either add a .noSwipe class the element, or set your own selector in the excludedElements property. |
| preventDefaultEvents | data-prevent-default-events | true | Call preventDefault on events |
| Method | Params | Description |
|---|---|---|
| enable | Enable touch and swipe | |
| disable | Disable touch and swipe |


var Whispers = require('whispers')
, _ = require('../util')
, comparisons = require('./comparisons');
module.exports = function(userProxy) {
var users = [];
var events = new Whispers();
Hub is designed to act as a mediator and doorway between users and the main application. Users should be passed into Hub through the connect method, which takes a socket as an argument. Once connected, Hub listens for a registration event, at which point a user will be built using the user proxy supplied at construction and added to the user list.
Hub reveals 4 important methods.
Accepts a socket and waits for a registration event before building a new proxy for the user and adding it to the user list.
var Whispers = require('whispers')
, _ = require('../util')
, comparisons = require('./comparisons');
module.exports = function(userProxy) {
var users = [];
var events = new Whispers();
(socket)
Accepts a socket (designed to be used with socket.io)
and listens for a registration event from the socket,
upon registration, builds a proxy from the user proxy
and adds it to users.
function connect(socket) {
socket.on('register', function(settings) {
var proxy, index;
Add the user to the users list
proxy = userProxy(user, settings);
index = users.push(proxy) - 1;
Fire a registration event
events.say('registration', proxy);
Remove this user when they disconnect
socket.on('disconnect', function() {
var users = users.splice(index, 1);
events.say('disconnect', users[0]);
});
});
};
Returns a query function based on a metric, comparator, threshold and an optional user set. Example use:
var session = Hub.select('session', '==', 3);
Now calling session()
will yield a user set of all
the users who’s session property === 3.
For flexibility and advanced querying you can pass a function as the comparator value. The function must accept two inputs and return a boolean value.
Calling select without the user set parameter will default to using users. Otherwise, queries will be performed on this subset.
function select(metric, comparator, threshold, set) {
if(_.undef(set)) {
set = users;
}
If no arguments are passed, return every user
if(arguments.length === 0) {
return set;
}
Otherwise, all arguments must be defined
if(_.undef(metric, comparator, threshold)) {
throw new Error('One or more select arguments were undefined');
}
Metric must be a string
if(!_.type(metric, 'string')) {
throw new Error('Metric must be a string');
}
Comparator must be a function or a sign
if(!_.type(comparator, 'function')) {
if(_.type(comparator, 'string')) {
if(!comparisons[comparator]) {
throw new Error('When passed as a string, comparator must be '
+ ' one of the following' + Object.keys(comparisons));
}
No error was thrown, get comparison function based on the comparator symbol
comparator = comparisons[comparator];
} else {
console.log(comparator, typeof comparator);
throw new Error('Comparator must be a comparison function, or a string');
}
}
Threshold must be a number
if(!_.type(threshold, 'number')) {
throw new Error('Threshold must be a number');
}
Return a function that will give the results of the query when called.
var result = set.filter.bind(users, function(user) {
Filter out users based on some metric, comparing it against the threshold with our comparator funtion.
return comparator(user[metric], threshold);
});
Provide iterator method for result set
result.each = function(iterator) {
var userSet = result();
for(var i = 0; i < userSet; i++) {
iterator(userSet[i], i);
}
};
Provide global emit for sockets in result set
result.emit = function() {
result.each(function(user) {
user.socket.emit.apply(user.socket, arguments);
});
};
Set some property of all users in this set
result.set = function(property, value) {
result.each(function(user) {
user[property] = value;
});
}
Provides chainable interface so that we can chain another selection onto an existing result set.
result.and = function(metric, comparator, threshold) {
arguments[arguments.length] = result();
return select.bind(this, arguments);
};
return result;
};
return {
connect: connect,
select: select,
all: select,
on: events.on
};
};


HURRICAINE TOPICAL ANESTHETIC - benzocaine gel
Beutlich Pharmaceuticals, LLC
Disclaimer: Most OTC drugs are not reviewed and approved by FDA, however they may be marketed if they comply with applicable regulations and policies. FDA has not evaluated whether this product complies.
Active ingredient
Benzocaine 20%
Uses
for the
temporary relief of occasional minor irritation and pain, associated with
- canker
sores
- sore mouth
and throat
- minor
injury of the mouth and gums
- minor
dental procedures
- minor
irritation of the mouth and gums caused by dentures or orthodontic appliances
Warnings
Allergy alert: Do not use if you have a history of allergy to local anesthetics such as procaine, butacaine, benzocaine or other "caine" anesthetics.
Stop use and ask a doctor
- if sore throat is severe, persists for more than 2 days, is accompanied or followed by fever, headache, rash, swelling, nausea, or vomiting
- if sore mouth symptoms do not improve in 7 days, or irritation, pain, or redness persists or worsens
Keep out of reach of children.
If more than used for pain is accidentally swallowed, get medical help or contact a Poison Control Center immediately.
Directions
- do not exceed recommended dosage
adults and children 2 years of age and older: apply to the affected area. Allow to remain in place at least 1 minute and then spit out. Use up to 4 times daily or as directed by a dentist or doctor.
children under 12 years of age: should be supervised in the use of the product
children under 2 years of age: consult a dentist or doctor
Other information
- do not use if imprinted seal under cap is broken or missing
- store at 20°-25° C (68°- 77° F)
Inactive ingredients
flavor, polyethylene glycol, sodium saccharin
Questions or comments?
1-800-238-8542
M-F: 8:00 a.m. - 4:30 p.m. ET
Principal Display Panel
NDC 0283-0871-31
HURRICAINE®
Topical Anesthetic GEL
20% Benzocaine Oral Anesthetic
ORIGINAL WILD CHERRY
Manufactured for:
Beutlich® Pharmaceuticals, LLC
Bunnell, FL 32110
1 oz.