Import Image
Import Image
In[]:=
wingsImage=Import["https://pbs.twimg.com/media/DqELgT7XQAYcaj8.jpg"];
In[]:=
ImageResize[wingsImage,500]
Out[]=
Text recognition
Text recognition
Use TextRecognize to see if you can get decent results. I found by increasing the image size, I could get better results:
In[]:=
text=TextRecognize[ImageResize[wingsImage,Scaled[3.5]]]
Out[]=
WINGS4 Chicken Wings 4.55 24 Chicken Wings 27.255 Chicken Wings 5.70 2_5 Chicken Wings 27.80 A- 16 Chicken Wings 6.80 26 Chicken Wings 28.957 Chicken Wings 7.95 27 Chicken Wings 30.108 Chicken Wings 9.10 n 28 Chicken Wings 31.201 9 Chicken Wings 10.20 29 Chicken Wings 32.35 I10 Chicken Wings 11.35 k 30 Chicken Wings 33.501.1 Chicken Wings 12.50 1 35 Chicken Wings 39.15' l1i 12 Chicken Wings 13.60 I 40 Chicken Wings 44.801 13 Chicken Wings 14.75 i i 45 Chicken Wings 50.5014 Chicken Wings 15.90 1' i 50 Chicken Wings 55.601 15 Chicken Wings 17.00 3 2 60 Chicken Wings 67.0016 Chicken Wings 18.15 70 Chicken Wings 78.3017 Chicken Wings 19.30 ` 75 Chicken Wings 83.4518 Chicken Wings 20.40 i 1 80 Chicken Wings 89.1019 Chicken Wings 21.55 90 Chicken Wings 100.45\20 chicken Wings 22.70 'f 100 chicken Wings 111.25x21 Chicken Wings 23.80 ` E 125 Chicken Wings 139.00, 22 Chicken Wings 24.95 150 Chicken Wings 166.85\23 Chicken Wings 26.10 200 Chicken Wings 222.50_.- .-.___-_ v`_.__`.._
Do some cleanup to make numbers work out:
In[]:=
textFixed=StringReplace[text,{Except[LetterCharacter|"."|DigitCharacter|WhitespaceCharacter]""}]
Out[]=
WINGS4 Chicken Wings 4.55 24 Chicken Wings 27.255 Chicken Wings 5.70 25 Chicken Wings 27.80 A 16 Chicken Wings 6.80 26 Chicken Wings 28.957 Chicken Wings 7.95 27 Chicken Wings 30.108 Chicken Wings 9.10 n 28 Chicken Wings 31.201 9 Chicken Wings 10.20 29 Chicken Wings 32.35 I10 Chicken Wings 11.35 k 30 Chicken Wings 33.501.1 Chicken Wings 12.50 1 35 Chicken Wings 39.15 l1i 12 Chicken Wings 13.60 I 40 Chicken Wings 44.801 13 Chicken Wings 14.75 i i 45 Chicken Wings 50.5014 Chicken Wings 15.90 1 i 50 Chicken Wings 55.601 15 Chicken Wings 17.00 3 2 60 Chicken Wings 67.0016 Chicken Wings 18.15 70 Chicken Wings 78.3017 Chicken Wings 19.30 75 Chicken Wings 83.4518 Chicken Wings 20.40 i 1 80 Chicken Wings 89.1019 Chicken Wings 21.55 90 Chicken Wings 100.4520 chicken Wings 22.70 f 100 chicken Wings 111.25x21 Chicken Wings 23.80 E 125 Chicken Wings 139.00 22 Chicken Wings 24.95 150 Chicken Wings 166.8523 Chicken Wings 26.10 200 Chicken Wings 222.50. .. v...
String processing
String processing
The cleaned up data looks good. With a simple StringExpression, I can make an Association of wing number to price:
In[]:=
wingCountToPriceRaw=Association[StringCases[textFixed,n:NumberString~~Whitespace~~"chicken"~~Whitespace~~"wings"~~Whitespace~~price:NumberString(ToExpression[n]ToExpression[price]),IgnoreCaseTrue]]
Out[]=
44.55,2427.25,55.7,2527.8,66.8,2628.95,77.95,2730.1,89.1,2831.2,910.2,2932.35,1011.35,3033.5,1.112.5,3539.15,1213.6,4044.8,1314.75,4550.5,1415.9,5055.6,1517.,6067.,1618.15,7078.3,1719.3,7583.45,1820.4,8089.1,1921.55,90100.45,2022.7,100111.25,2123.8,125139.,2224.95,150166.85,2326.1,200222.5
I can make the prices be actual dollars with Quantity:
In[]:=
wingCountToPrice=Quantity[#,"USDollars"]&/@KeySort[wingCountToPriceRaw]
Out[]=
1.1,4,5,6,7,8,9,10,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,35,40,45,50,60,70,75,80,90,100,125,150,200
I noticed that 11 was mistaken as 11, so I’ll fix it manually:
Now, the data is in a nice structure:
Verify Data
Verify Data
Let’s make a grid to check that the data is correct:
Simple Analysis
Simple Analysis
Many people made many plots like these:
Price vs Wing Count
Price vs Wing Count
Price per Wing vs Wing Count
Price per Wing vs Wing Count
Nutrition Information
Nutrition Information
Pregenerate up to 100 to make page load times faster:
Copy them to the cloud:
Make a top-level function that decides how to get the image:
Minimizing cost
Minimizing cost
It’s cheapest to buy sets of 25 wings:
If you’re buying less than 25, then it’s cheapest to buy multiples of three:
Minimize cost for a given number of wings
Minimize cost for a given number of wings
Find the cheapest and most expensive ways to buy a given number of wings using FrobeniusSolve:
Investigate performance
Investigate performance
For numbers below 50, they take less than a few seconds each to generate all solutions:
The number of solutions increases dramatically for larger numbers, so a heuristic must be used above 50 to limit the number of solution and keep decent performance .
Make readable result
Make readable result
Package up into a readable result:
Deploying something to the cloud
Deploying something to the cloud
Deploy an interactive form in the cloud
Deploy an interactive form in the cloud
Copy this notebook to the cloud
Copy this notebook to the cloud
This allows others to see it in the cloud with ease: