Programming Fundamentals - Lab 4 - Solution

EXERCISE
Ask the user for the current amount of Bitcoin that they own.
Using the Ruby hash `bitcoin_data`, display a summary of  Bitcoin data for the user.  Something like the output below.

Sample output:
1 Bitcoin is valued at $41405.1046 USD.
Your Bitcoin is worth $62107.6569.

This lab includes some starting code.  At the top of the file are several lines of code that will pull live bitcoin data from the Coindesk API.  We'll learn more about APIs later, but essentially an API is how another software application exposes some of its data or functionality programmatically.  As a user, we might visit the coindesk.com to see the current value of Bitcoin.  But if we want our code to get that data, we have retrieve it programmatically.  That's what the code at the top of the file does:

# DON'T CHANGE THIS CODE
# ----------------------
require "net/http"
require "json"
url = "https://api.coindesk.com/v1/bpi/currentprice.json"
uri = URI(url)
response = Net::HTTP.get(uri)
bitcoin_data = JSON.parse(response)
# ----------------------

It will connect to a special API url, convert the response from that url into a ruby hash, and then assign it to a variable bitcoin_data.

Aside from this code, the lab also includes code for the first steps - asking the user for how much Bitcoin they own:

puts "How much bitcoin do you have?"
bitcoin = gets.chomp
bitcoin = bitcoin.to_f

The code gets.chomp is sort of the opposite of puts.  puts displays text output.  gets accepts text input and will pause the application waiting until a user types in something and presses enter.  The .chomp part is needed because the text that gets captures includes the enter key that is pressed, but since we're not interested in that key, we drop it using .chomp.  When a user enters a value, it gets stored as a string (gets stands for "get string"), so we need to convert it to a numerical Float so that we can perform mathematical calculations with it.

Run the program and you will see that it pauses and waits for you to enter something.  Once you do, it will continue and end.

Next, we can look at the bitcoin_data hash with puts bitcoin_data (note that the sample hash below will have the current values when you run your code).

{
  "time": {
    "updated": "Apr 21, 2022 05:52:00 UTC",
    "updatedISO": "2022-04-21T05:52:00+00:00",
    "updateduk": "Apr 21, 2022 at 06:52 BST"
  },
  "disclaimer": "This data was produced from the CoinDesk Bitcoin Price Index (USD). Non-USD currency data converted using hourly conversion rate from openexchangerates.org",
  "chartName": "Bitcoin",
  "bpi": {
    "USD": {
      "code": "USD",
      "symbol": "$",
      "rate": "41,463.2367",
      "description": "United States Dollar",
      "rate_float": 41463.2367
    },
    "GBP": {
      "code": "GBP",
      "symbol": "£",
      "rate": "31,768.9661",
      "description": "British Pound Sterling",
      "rate_float": 31768.9661
    },
    "EUR": {
      "code": "EUR",
      "symbol": "€",
      "rate": "38,277.4089",
      "description": "Euro",
      "rate_float": 38277.4089
    }
  }
}

It's hash of key-value pairs - we know this because of the curly braces ({}).  Looking closely at it, the top level of the hash has 4 keys: "time", "disclaimer", "chartName", "bpi".  The value of the "bpi" key appears to have the rate data that we're looking for.  Specifically, it's also a hash of key-value pairs and the keys are different currencies.  Looking into "USD" key, there are several keys, but 2 that seem relevant: "rate" and "rate_float".  Notice that the value of the "rate" key is a string (denoted by the quotes around it), whereas the value of the "rate_float" key appears to be numeric.  In order to perform mathematical calculations, we'll want the numeric value.

Now that we've dug into the hash and found the data that we want, let's assign it to a variable:

usd_rate = bitcoin_data["bpi"]["USD"]["rate_float"]
puts usd_rate

It never hurst to display a value as a sanity check that your code is working.

Next, we should calculate the value in USD of the user's bitcoin which is stored in the bitcoin variable:

usd_value = usd_rate * bitcoin
puts usd_value

And finally, we can display the output.  Let's start by displaying the full sample text without any dynamic variables:

puts "1 Bitcoin is valued at $41405.1046 USD."
puts "Your Bitcoin is worth $62107.6569."

Now we just need to replace the parts of the text with the real data.

puts "1 Bitcoin is valued at $#{usd_rate} USD."
puts "Your Bitcoin is worth $#{usd_value}."

The final code:

puts "How much bitcoin do you have?"
bitcoin = gets.chomp
bitcoin = bitcoin.to_f

usd_rate = bitcoin_data["bpi"]["USD"]["rate_float"]
usd_value = usd_rate * bitcoin

puts "1 Bitcoin is valued at $#{usd_rate} USD."
puts "Your Bitcoin is worth $#{usd_value}."

Challenge

Could you take this a step further?  Use another gets.chomp to ask the user for which currency they want (USD, GBP, EUR).  If the user doesn't enter any of those, show them an error.  Otherwise, modify the code above to display the rate and calculated value in the user's desired currency.