Before it gets started
This is my first create-from-zero project in Flatiron School. It’s a Command Line Interface Ruby Gem that you should process and interact with user using data you get from no matter using API or scraping from a website. After seeing the weather app project created by Annabel who has inspired me a lot as my cohort leader, I realized this project is going to be a great opportunity to revise and integrate all the knowledge we’ve learnt in Phase 1.
Come up with your own idea
I’m a huge soccer fan and an ardent Juventus club supporter. Naturally my first idea is to build a program to inquire all kind of information about this team or the league this team belongs to.
Scraping or API
After knowing what kind of information I need, the next step is to figure out in what way can you get down the data. I checked the official webpage of some famous soccer clubs and leauges because subconsciously I thought scraping was very time-consuming to go through a webpage and inspect labels. All I found out was that they didn’t have that kind of APIs. It turned out that I still had to face scraping.
In fact scraping is fun
I went on this spanish soccer league ranking page on espn and I found out you could easily get access to different league information just by changing the suffix which actually was an abbreviation of that country. This means I can get whichever league information just by passing in only one argument as long as these pages have the same layout. So I dug in a little deeper to make sure it was on the same page with me, in the meanwhile I created a test ruby file in VSCode.
Nailed it! But here came along the problems. The data table on the webpage placed team information on the left but team data on the right. They were in different containers.
There are eight types of data in soccer league ranking chart which are game played, wins, draws, losses, goals for, goals against, goal difference and points, respectively. But data I could get was continuous, I have to manually cut the data every eight piece to store them.
This was how I cut the data. By dispensing different data to different hash. But soon I found out another problem that every team’s data would be coverd by the last team’ data. And the reason was that I only created one hash called team_stats which all the data was operating on it. So I made some changes to the method.
I know for now I was only incorporating three leagues which all have 20 teams, so I created an array with 20 empty hashes in it so that every team data could be store in respective hashes by the new index x. But this would be another limitation if I would like to scrape from a league which has different numbers of teams.
Running all the way
I spent the first night baring my headache to test out whether my method worked properly. Finally I got what I wanted. I could go to sleep like a fulfilled baby because I knew at that time it’s going to be running all the way. I finished most parts of other two main classes CLI and Team the next day. The key of Team class or whichever model class the serves the purpose to store your data is mass assignment.
At that time this team_hash argument’s key was only team name, so I wrote two methods to assign value to every team objects. I will explain #deprecated later.
CLI class is basiclly just a playground you manipulate all your scraped data and model instances together within designed user interaction flow control.This is the only class that you could use PUTS and GETS. For me the key in this class is ABSTRACTION. Because when you have lots of business logic you have to find a way to manage your code.
At first I just designed some basic functions for user to check ranking, teams going to UCL next season(top 4), teams going to EL next season(fifth), teams might be downgraded(last 3) and detail formatted data of certain team. The project has this requirement that it shouldn’t require the same data twice in one run. But I had only one Team class to store team objects in it’s class variable @@all. This would lead to a contradiction between the requirement and my accuracy in detail data of certain team.(check ita league first the esp league team’s rank would be starting from 21.).Also I wanted to add some more functionalities to this program such as Top 10 score players and Top 10 assist players. I needed a way to figure these out.
Be enlightened all of a sudden
As I was reviewing my code I found out that I used two steps to generate one complete team object. However in fact I’m able to pass in juet one hash with more details to implemet that. The return value of #create_teams is an array with hashes in it and the counts of this array is dynamic! Awesome! I refactored #add_stats method by passing in #create_teams’ return value as an argument. Problem solved! So far I officially annouce #add_attributes and .complete_team_stats these two methods’ retirement(#deprecated)! Now I could scrape any league disregarding its team quantity. Then I created a League class to store different league so that it doesn’t have to scrape again if users want to see some information they’ve checked before. And I can create some properties to build up the league rules about UCL, UL ,relegation quota instead of hard code. Lastly I will have a place to store score ranking and assist ranking data!
Words in the end
I really had some fun in the process of this project.
Shout out to my favorite soccer club in Italian. Forza Juve!