Advertisement
Guest User

Untitled

a guest
Oct 10th, 2016
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 12.94 KB | None | 0 0
  1. // Divvy Ride Analysis
  2. //
  3. // << Aloysius Paredes >>
  4. // U. Of Illinois, Chicago
  5. // CS 341, Fall 2016
  6. // HW #04
  7.  
  8. #light
  9.  
  10. // Prompt user for a folder name, and then return a list of all the
  11. // files in that folder.  Returns empty list if folder doesn't exist
  12. // or cannot be found.
  13. let GetFilenames() =
  14.   printf "Please enter folder name> "
  15.   let folder = System.Console.ReadLine()
  16.   if not (System.IO.Directory.Exists folder) then
  17.     []
  18.   else
  19.     folder
  20.     |> System.IO.Directory.GetFiles
  21.     |> Array.toList
  22. //end GetFilenames()
  23.  
  24. // Parse one line of CSV data from a Divvy data file.
  25. // trip_id,bikeid,tripduration,from_station_id,to_station_id,gender,birthyear
  26. // Right now the function returns a list of two integer elements: [tripID; bikeID].
  27. let private ParseLine (line:string) =
  28.   let elements = line.Split(',')
  29.   let tripID = System.Convert.ToInt32(elements.[0])
  30.   let bikeID = System.Convert.ToInt32(elements.[1])
  31.   let duration = System.Convert.ToInt32(elements.[2])
  32.   let fromStationID = System.Convert.ToInt32(elements.[3])
  33.   let toStationID = System.Convert.ToInt32(elements.[4])
  34.  
  35.   //change the gender to integer values
  36.   //male = 1, female = 2, ? = 3
  37.   let genderTranslate gender =
  38.     match gender with
  39.     | "Male"    -> 1
  40.     | "Female"  -> 2
  41.     | _         -> 3
  42.  
  43.   let gender = genderTranslate elements.[5]
  44.   let birthYear = System.Convert.ToInt32(elements.[6])
  45.  
  46.   //return the values as a small list of integers
  47.   [tripID; bikeID; duration; fromStationID; toStationID; gender; birthYear]
  48. //end ParseLine(line:string)
  49.  
  50.  
  51. //
  52. // Parses 1 file of Divvy data, where the format of each line is
  53. // discussed above; returns back a list of elements where the format
  54. // of each element is discussed above.
  55. // NOTE: the "|>" means pipe the data from one function to
  56. // the next.  The code below is equivalent to letting a var
  57. // hold the value and then using that var in the next line.
  58. let private ParseDivvyFile filename =
  59.   System.IO.File.ReadLines(filename)
  60.   |> Seq.skip 1  // skip header row:
  61.   |> Seq.map ParseLine
  62.   |> Seq.toList
  63. //end ParseDivvyFile
  64.  
  65. //function to return the number of members
  66. let countMembers data =
  67.   //create a sublist from element 5 (gender = 1 or 2 or 3) from the data list
  68.   let riders = List.map (fun sublist -> List.item 5 sublist ) data
  69.   //create sublist of males
  70.   let males = riders |> List.filter(fun x -> x = 1)
  71.   //create sublist of females
  72.   let females = riders |> List.filter(fun x -> x = 2)
  73.   //sum up the number of males and number of females
  74.   let count = males.Length + females.Length
  75.   //return the sum
  76.   count
  77. //end countMembers
  78.  
  79. //function to create a sublist of number of members from the data list
  80. let getMembers data =
  81.   let y = List.map(fun x -> countMembers x) data
  82.   y
  83.  
  84. //function to return number of nonmembers
  85. let countNonMembers data =
  86.   //create a sublist from element 5 (gender = 1 or 2 or 3) from the data list
  87.   let riders = List.map(fun sublist -> List.item 5 sublist) data
  88.   //create a sublist of unknowns (not male and not female)
  89.   let unknowns = riders |> List.filter(fun x -> x = 3)
  90.   //return the length of the unknowns list
  91.   let count = unknowns.Length
  92.   count
  93. //end countNonMembers
  94.  
  95. //function to create a sublist of number of nonmembers from the data list
  96. let getNonMembers data =
  97.   let y = List.map(fun x -> countNonMembers x) data
  98.   y
  99.  
  100. //function to return men percentage
  101. let calculateMenPercentage data =
  102.   //create a sublist from element 5 (gender = 1 or 2 or 3) from the data list
  103.   let riders = List.map(fun sublist -> List.item 5 sublist) data
  104.   //create sublist of males
  105.   let males = riders |> List.filter(fun x -> x = 1)
  106.   //create sublist of females
  107.   let females = riders |> List.filter(fun x -> x = 2)
  108.   //sum up the number of males and number of females
  109.   let total = float(males.Length + females.Length)
  110.   //calculate percentage = numMales / total
  111.   let percentage = (float(males.Length) / total) * 100.0
  112.   //return the percentage of men
  113.   percentage
  114. //end calculateMenPercentage
  115.  
  116. //function to create a sublist of % of men
  117. let getMenPercentage data =
  118.   let y = List.map(fun x -> calculateMenPercentage x) data
  119.   y
  120.  
  121. let malePercent data =
  122.   let genders = List.map (List.map (fun x -> List.item 5 x )) data
  123.   let not3 = List.map (List.filter(fun x -> x <> 3)) genders
  124.   let totals = List.map (fun x -> List.length x) not3
  125.   let males = List.map(List.filter(fun x -> x = 1)) genders
  126.   let numMales = List.map(List.length) males
  127.  
  128.   let tuple = List.zip numMales totals
  129.  
  130.   let percentages = List.map (fun x -> (float(fst x) / float(snd x) * 100.0)) tuple
  131.  
  132.   percentages
  133.  
  134. //function to return women percentage
  135. let calculateWomenPercentage data =
  136.   //create a sublist from element 5 (gender = 1 or 2 or 3) from the data list
  137.   let riders = List.map(fun sublist -> List.item 5 sublist) data
  138.   //create sublist of males
  139.   let males = riders |> List.filter(fun x -> x = 1)
  140.   //create sublist of females
  141.   let females = riders |> List.filter(fun x -> x = 2)
  142.   //sum up the number of males and number of females
  143.   let total = float(males.Length + females.Length)
  144.   //calculate percentage = numMales / total
  145.   let percentage = (float(females.Length) / total) * 100.0
  146.   //return the percentage of women
  147.   percentage
  148. //end calculateMenPercentage
  149.  
  150. //function to create a sublist of % of women
  151. let getWomenPercentage data =
  152.   let y = List.map(fun x -> calculateWomenPercentage x) data
  153.   y
  154.  
  155. //function to return number of males
  156. let totalMale data =
  157.   //create a sublist from element 5 (gender = 1 or 2 or 3) from the data list
  158.   let riders = List.map(fun sublist -> List.item 5 sublist) data
  159.   //create sublist of males
  160.   let males = riders |> List.filter(fun x -> x = 1)
  161.   //return number of males
  162.   males.Length
  163. //end totalMale
  164.  
  165. //function to create a sublist of total number of males
  166. let getMales data =
  167.   let y = List.map(fun x -> totalMale x) data
  168.   y
  169.  
  170. //function to return number of females
  171. let totalFemale data =
  172.   //create a sublist from element 5 (gender = 1 or 2 or 3) from the data list
  173.   let riders = List.map(fun sublist -> List.item 5 sublist) data
  174.   //create sublist of males
  175.   let females = riders |> List.filter(fun x -> x = 2)
  176.   //return number of males
  177.   females.Length
  178. //end totalFemale
  179.  
  180. //function to create a sublist of total number of females
  181. let getFemales data =
  182.   let y = List.map(fun x -> totalFemale x) data
  183.   y
  184.  
  185.  
  186. //function to calculate male age
  187. let calculateMaleAge data =
  188.   //variable to hold the current year
  189.   let curYear = System.DateTime.Now.Year
  190.   //create a sublist from element 5 from the data list
  191.   let riders = List.map(fun sublist -> List.item 5 sublist) data
  192.   //create a sublist from element 6 from the data list
  193.   let allBirthYears = List.map(fun sublist -> List.item 6 sublist) data
  194.   //create a sublist of tuples holding gender and birthyear
  195.   let riderAndBirths = List.zip riders allBirthYears
  196.   //filter out the females and unknowns
  197.   let maleBirths = riderAndBirths |> List.filter(fun x -> fst x = 1)
  198.   //create a list of just birthyears (should be male)
  199.   let males, birthYears = List.unzip maleBirths
  200.   //create a sublist of ages
  201.   let ages = List.map(fun x -> if x = 0 then 0 else curYear - x) birthYears
  202.   //return the sum of all ages per month
  203.   List.sum ages
  204. //end calculateMaleAge
  205.  
  206. //function to create a sublist of male ages
  207. let getMaleAges data =
  208.   let y = List.map(fun x -> calculateMaleAge x) data
  209.   y
  210.  
  211. //function to calculate male age
  212. let calculateFemaleAge data =
  213.   //variable to hold the current year
  214.   let curYear = System.DateTime.Now.Year
  215.   //create a sublist from element 5 from the data list
  216.   let riders = List.map(fun sublist -> List.item 5 sublist) data
  217.   //create a sublist from element 6 from the data list
  218.   let allBirthYears = List.map(fun sublist -> List.item 6 sublist) data
  219.   //create a sublist of tuples holding gender and birthyear
  220.   let riderAndBirths = List.zip riders allBirthYears
  221.   //filter out the males and unknowns
  222.   let femaleBirths = riderAndBirths |> List.filter(fun x -> fst x = 2)
  223.   //create a list of just birthyears (should be female)
  224.   let females, birthYears = List.unzip femaleBirths
  225.   //create a sublist of ages
  226.   let ages = List.map(fun x -> if x = 0 then 0 else curYear - x) birthYears
  227.   //return the sum of all ages per month
  228.   List.sum ages
  229. //end calculateFemaleAge
  230.  
  231. //function to create a sublist of male ages
  232. let getFemaleAges data =
  233.   let y = List.map(fun x -> calculateFemaleAge x) data
  234.   y
  235.  
  236. //calculate durations 1-30min
  237. let calculateDuration1 data =
  238.   //create a sublist from element 2 from the data list
  239.   let durations = List.map(fun sublist -> List.item 2 sublist) data
  240.   //filter out anything that's not 1-30min
  241.   let neededDuration = durations |> List.filter(fun x -> x <= 1800)
  242.   //return the number of 1-30min durations
  243.   neededDuration.Length
  244. //function to create a sublist of 1-30 min durations
  245. let getDurations1 data =
  246.   let y = List.map(fun x -> calculateDuration1 x) data
  247.   y
  248.  
  249. //calculate durations 31-60min
  250. let calculateDuration2 data =
  251.   //create a sublist from element 2 from the data list
  252.   let durations = List.map(fun sublist -> List.item 2 sublist) data
  253.   //filter out anything that's not 31-60min
  254.   let neededDuration = durations |> List.filter(fun x -> x > 1800 && x <= 3600)
  255.   //return the number of 31-60min durations
  256.   neededDuration.Length
  257. //function to create a sublist of 1-30 min durations
  258. let getDurations2 data =
  259.   let y = List.map(fun x -> calculateDuration2 x) data
  260.   y
  261.  
  262. //calculate durations 61-120min
  263. let calculateDuration3 data =
  264.   //create a sublist from element 2 from the data list
  265.   let durations = List.map(fun sublist -> List.item 2 sublist) data
  266.   //filter out anything that's not 31-60min
  267.   let neededDuration = durations |> List.filter(fun x -> x > 3600 && x <= 7200)
  268.   //return the number of 61-120min durations
  269.   neededDuration.Length
  270. //function to create a sublist of 1-30 min durations
  271. let getDurations3 data =
  272.   let y = List.map(fun x -> calculateDuration3 x) data
  273.   y
  274.  
  275. //calculate durations 121+min
  276. let calculateDuration4 data =
  277.   //create a sublist from element 2 from the data list
  278.   let durations = List.map(fun sublist -> List.item 2 sublist) data
  279.   //filter out anything that's not 121+min
  280.   let neededDuration = durations |> List.filter(fun x -> x > 7200)
  281.   //return the number of 121+min durations
  282.   neededDuration.Length
  283. //function to create a sublist of 1-30 min durations
  284. let getDurations4 data =
  285.   let y = List.map(fun x -> calculateDuration4 x) data
  286.   y
  287.  
  288. [<EntryPoint>]
  289. let main argv =
  290.   printfn ""
  291.   printfn "** Divvy Ride Analysis **"
  292.   printfn ""
  293.   //
  294.   let files = GetFilenames()
  295.   //
  296.   // input the data into a LIST OF LISTS, one per file.  The format
  297.   // of each sub-list is determined by the "ParseDivvyFile" function:
  298.   //
  299.   let data = List.map ParseDivvyFile files
  300.   //
  301.   // printfn "%A" data   // debugging to see data format:
  302.   //
  303.   printfn ""
  304.   printfn "** # of rides:  %A" (List.map List.length data)
  305.  
  306.   let numMembersList = getMembers data
  307.   //get the members list
  308.   printfn "** Members:     %A" (numMembersList)
  309.   let numNonMembersList = getNonMembers data
  310.   //get the nonmembers list
  311.   printfn "** Non-Members: %A" (numNonMembersList)
  312.  
  313.   //get the percentage of men list
  314.   let menPercentage = getMenPercentage data
  315.   printfn ""
  316.   printfn "** %% of men:    %A" (menPercentage)
  317.   //get the percentage of women list
  318.   let womenPercentage = getWomenPercentage data
  319.   printfn "** %% of women:  %A" (womenPercentage)
  320.  
  321.   //variable to hold total number of males and females
  322.   let totalNumMales = List.sum (getMales data)
  323.   let totalNumFemales = List.sum (getFemales data)
  324.   //variable to hold sum of male and female ages
  325.   let maleAges = List.sum (getMaleAges data)
  326.   let femaleAges = List.sum (getFemaleAges data)
  327.   printfn ""
  328.   printfn "** Average age:"
  329.   //get average age of men
  330.   printfn "   Men:   %A" (float(maleAges) / float(totalNumMales))
  331.   //get average age of women
  332.   printfn "   Women: %A" (float(femaleAges) / float(totalNumFemales))
  333.  
  334.   //variable to hold total rides
  335.   let totalRides = float(List.sum (List.map List.length data))
  336.   //variables to hold filtered durations
  337.   let durations1 = getDurations1 data
  338.   let durations2 = getDurations2 data
  339.   let durations3 = getDurations3 data
  340.   let durations4 = getDurations4 data
  341.  
  342.   printfn ""
  343.   printfn "** Ride Durations:"
  344.   printfn "   1..30   mins: %A (%A%%)" (List.sum durations1) ((float(List.sum durations1) / totalRides) * 100.0)
  345.   printfn "   31..60  mins: %A (%A%%)" (List.sum durations2) ((float(List.sum durations2) / totalRides) * 100.0)
  346.   printfn "   61..120 mins: %A (%A%%)" (List.sum durations3) ((float(List.sum durations3) / totalRides) * 100.0)
  347.   printfn "   121+    mins: %A (%A%%)" (List.sum durations4) ((float(List.sum durations4) / totalRides) * 100.0)
  348.  
  349.  
  350.   //let maleAverage = malePercent data
  351.   //printfn "** Men Avg:     %A" (maleAverage)
  352.   //
  353.   // done:
  354.   //
  355.   printfn ""
  356.   printfn "** Done **"
  357.   printfn ""
  358.   printfn ""
  359.   0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement