Trying to pull from API with Ruby -- how to pass variable into string? - ruby

Im trying to practice pulling APIs with Ruby. Im trying to pull videogame news from Steam.
Below is my code.
The idea is, when the program is ran, the the user is prompted to enter a game ID between 200 and 440.
Anything not in between dont exist or the numbers arent continuous.
Anyway, Im trying to pass the gameID variable into the string:
"http://api.steampowered.com/ISteamNews/GetNewsForApp/v0002/?appid=#{gameID}&count=5&maxlength=300&format=json"
The string is wrapped in a function. When I try to run the program, the error says wrong number of arguments ( 0 for 1 ).
What am i doing wrong, and what am I missing? Many thanks in advance as usual :)
*been doing nothing but asking questions so far, hope to contribute someday once I get better :)
require 'json'
require 'HTTParty'
puts "----------------------------------------------------------"
puts "Welcome to my practice"
puts "The purpose of this exercise is to use the SteamAPI"
puts "to pull videogame news from Steam"
puts "----------------------------------------------------------"
reset = true
while reset
puts "Please enter a game ID between 200 - 440"
gameID = gets.to_i
if gameID < 200
puts "--Invalid input--"
reset = true
elsif gameID > 400
puts "--Invalid input--"
reset= true
else
reset = false
end
end
puts "--------------------Loading API----------------------------"
def get_news( gameID )
string = "http://api.steampowered.com/ISteamNews/GetNewsForApp/v0002/?appid=#{gameID}&count=5&maxlength=300&format=json"
page = HTTParty.get( string )
browse = page["appnews"]["newsitems"]
browse.map do |content|
{title: content["title"], contents: content["contents"]}
end
end
def display_story( content )
puts "Title: #{content[:title]}"
puts "--------------------"
puts " #{content[:contents]}"
puts "--------------------"
end
get_news.each do |content|
display_story( content )
end

You've defined get_news to take a gameID argument, but you haven't passed it anything. At the end of your file, you need get_news(gameID).each.

Related

Ruby - Create a class with a file as a variable - possible?

I need to create a program in which the user can take different tests. As i dont want to copy paste my code all over for every test, i have tried to setup a class for that purpose - but i have problems with this class.
Error message = undefined variables or method in 'display_test'
I have predefined som test as a .txt file
I want to choose the file in the class depending on what the user answer - is that possible?
Class code:
class Test
#correct_answers = 0
def display_question( question, options, answer )
puts question
options.each_with_index { |option, idx| puts "#{ idx + 1 }: #{ option
}" }
print 'Answer: '
reply = gets.to_i
if answer == reply
puts 'Correct!'
#correct_answers += 1
puts "#{#correct_answers}"
else
puts 'Wrong. The correct answer was: ' + answer.to_s
end
end
def display_test()
f = File.new(userinput, 'r')
while ! (f.eof?) #logikken til at splitte
line = f.gets()
question = line.split("|")
question[1] = question[1].split(";")
display_question question[0], question[1], question[2].to_i
end
end
display_test
puts "________________________________________________________"
puts "Total score:"
puts "You've got" + " #{#correct_answers}" + " correct answers!"
Before hand i have used ("geografitest.txt") instead of username in the File.new so it looked like this:
f = File.new('geografitest.txt','r')
But now i am trying to let the user decide what test to take.
I am very new to ruby, so please bear with me.
I have tried to do it this way, which obviously is not working.
puts "Which test do you want to take?"
select = 0
while (select != 3)
puts "Press 1 to take Geografi test."
puts "Press 2 to take Math test."
puts "Press 3 to take Religion test."
puts "Press 3 to exit"
select = gets.chomp.to_i
if (select == 1)
gets.chomp = userinput
userinput =`geografitest.txt`
echo $userinput
end
if (select == 2)
gets.chomp = userinput
userinput =`matematiktest.txt`
echo $userinput
end
if (select == 3)
gets.chomp = userinput
userinput =`religionstest.txt`
echo $userinput
end
if (select > 4)
puts "Not a correct selection"
elsif (select == 4)
puts "Goodbye"
end
end
abort
So my questions is now;
How can i make the user choose what test to take? Can i make a variable instead of the textfile as i have tried, but in a different way? Or is there a smarter way?
And in what way is my class wrong and how do i fix it? I know its not the way to make it, but i simple cant get my head around how to make it right.
Please help a rookie out.
Cheers!
You can pass file as dependency to you Test class based on user input with object constructor. Something like this
class Test
attr_reader :correct_answers_count
def initialize(file)
#file = file
#correct_answers_count = 0
end
#other code goes here
end
loop do
case user_input = gets.chomp
when '1'
file_name = 'some_file1'
when '2'
file_name = 'some_file1'
when '3'
break
else
puts 'wrong variant'
end
test = Test.new(File.new(file_name, 'r'))
test.display
end

Deleting a row from a CSV file with Ruby

I've seen similar answers to this question but I think I need something more specific to my code. Basically I've called the row from the CSV file but now I need to delete the called row. Sounds simple as I write this yet here I am asking you all for help. I know there is a lot of code here but I figured the more there is the more easier you will be able to understand the context. Apologies if there is too much noise in the code.
def delete_user_menu
puts "============================================"
delete_users_active_list
puts " "
puts "Please type in the name of the user you wish to eradicate: "
print "> "
eradicate(gets.chomp)
end
def eradicate(delete_input)
delete_row = delete_authentication(delete_input)
if delete_row
puts "Are you sure you want to delete #{delete_input} from the database?"
puts "[y]es or [n]o"
print "> "
delete_answer = gets.chomp
if delete_answer == "y"
delete_user
after_deletion_menu
elsif delete_answer == "n"
puts "Close call! Taking you back to main menu."
sleep 2
admin_main_menu
else
puts "Input not recognised. Please try again."
eradicate(delete_input)
end
else
puts "User not recognized. Please try again."
sleep 1
delete_user_menu
end
end
def delete_user
# this is where the delete user function needs to go
after_deletion_menu
end
def after_deletion_menu
puts " "
puts "User deleted! What would you like to do now?"
puts "1. Delete another user"
puts "2. Back to main menu"
print "> "
after_deletion_choice = gets.chomp
if after_deletion_choice == "1"
delete_user_menu
elsif after_deletion_choice == "2"
admin_main_menu
else
puts "Input not recognized. Please try again."
after_deletion_menu
end
end
def delete_users_active_list
CSV.foreach("./users.csv", headers: true) do |row|
username = row['username']
puts "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
puts "Username: #{username}"
end
end
def delete_authentication(username)
CSV.open('users.csv', headers: true).find { |row| row['username'] == username }
end
I've had a look at this question How to remove a row from a CSV with Ruby
but I don't fully understand the answers, hence why I'm here. Any help is much appreciated.
I looked at the link. First, they are reading the entire csv file into table:
table = CSV.table(#csvfile)
then deleting the row from table:
table.delete_if do |row|
row[:foo] == 'true'
end
Finally, they are completely replacing the original file with the new table minus the row:
File.open(#csvfile, 'w') do |f|
f.write(table.to_csv)
end
This is generally how you have to do this kind of operation when you are dealing with a file. It's not like a database.
EDIT - in your case:
delete_user(delete_input)
...
def delete_user(user)
...
table.delete_if { |row| row[:username] == user }
...

Ruby: file output blank

So I'm trying to build a program which tells me how many days are left till someone's birthday. I have a text file that I'm drawing data from. The problem is the save method is not working for some reason, and nothing is being printed to the output file. Thank you so much in advance!
require 'date'
Person = Struct.new(:name, :bday)
module Family
Member = Hash.new
File.readlines("bday_info.txt").each do |line|
name, bday = line.split(',')
person = Person.new(name, bday)
Member[name] = bday
end
def self.next_bday(name)
birthday = Date.parse(Family::Member[name])
this_year = Date.new(Date.today.year, birthday.month, birthday.day)
next_year = Date.new(Date.today.year + 1, birthday.month, birthday.day)
if this_year > Date.today
puts "\n#{(this_year - Date.today).to_i} days to #{name}'s birthday"
else
puts "\n#{(next_year - Date.today).to_i} days to #{name}'s birthday"
end
end
def self.save(name)
File.open("days_left.txt", "w") do |file|
file.puts "#{next_bday(name)}"
end
end
end
loop do
puts "\nName:"
response = gets.chomp.capitalize
if response.downcase == "quit"
break
elsif Family::Member.has_key?("#{response}") == false
puts "\nYou ain't on the list"
else
Family.next_bday(response)
Family.save(response) #WHY IS THIS LINE NOT WORKING???
end
end
Your Family.next_bday does not return anything (to be more precise - it's returning nil that last puts returns), thus nothing is written to the file.
Other notes(not directly related):
No reason in calling Family.next_bday(response) twice, just save return value from the first call
Family::Member constant looks more like a variable, more clean design will be to make the whole thing a class that takes input file name, reads data in initializer and then stores into a instance variable

loop through json array and retrieve one attribute, gives errors also

i am new to programming in ruby, and i am trying to get the value of json['earning_rate_hr'] but i get an error, in '[]': no implicit conversion of String into Integer (TypeError)
i know and i understand the error, however this is not my main question here is my file :
checkingchecker.rb :
#require_relative '../lib/hackex/net/typhoeus'
require_relative '../lib/hackex'
require 'rubygems'
require 'json'
file = 'accounts1.txt'
f = File.open file, 'r'
puts "MADE BY THE PEOPLE, FOR THE PEOPLE #madebylorax"
puts ""
puts "--------------------------------------------------------"
puts ""
while line = f.gets
line = line.chomp.split(';')
email, password = line
puts "logging in as " + email
HackEx.LoginDo(email, password) do |http, auth_token, user|
puts "getting info..."
user = HackEx::Request.Do(http, HackEx::Request.UserInfo(auth_token))['user']
puts "receieved user info!"
bank = HackEx::Request.Do(http, HackEx::Request.UserBank(auth_token))['user_bank']
puts "recieved bank info!"
json = HackEx::Request.Do(http, HackEx::Request.UserSpam(auth_token))['spam']
puts "recieved spam info!"
puts json['earning_rate_hr'] #error line, the error is because this is an array, and it cant be turned into integer, i was wondering if there is a way to use puts on it without trying to make it an integer
userchecking = bank["checking"]
checking = userchecking.scan(/.{1,3}/).join(',')
puts email + " has in Checking: BTC #{checking}"
puts ""
puts "--------------------------------------------------------"
puts ""
end
end
i tried to do puts json, it puts items like this one :
{"id"=>"9867351", "user_id"=>"289108", "victim_user_id"=>"1512021",
"victim_ip"=
"86.60.226.175", "spam_level"=>"50", "earning_rate_hr"=>"24300", "total_earning s"=>"13267800", "started_at"=>"2015-11-01 07:46:59",
"last_collected_at"=>"2015- 11-24 01:46:59"}
what i want to do is select the earning_rate_hr for each one of them and add them together, however i do not have a clue on how to do that, since the error is not fixed and i cant get the value of it
ps : i tried turning it into a Hash, and i also tried using .first, but .first only shows the firs one, i want to show all of them, thank you
I know you from line messenger, I haven't used ruby codes in a long time and this one keeps giving me cloudflare errors, I'm not sure if its because of server downtime/maintainance or whatever but yeah anyway heres your script, enjoy farming ;) -LineOne
PS, I changed a few strings to make it look a lil cleaner so you can see the spam income easier, and added the sleep (1) because sleeping for one second before reconnecting helps to prevent cloudflare errors
also you don't need to require json or rubygems in your hackex scripts because its required in the library so its all covered pre-user-input/script
require_relative 'libv5/lib/hackex'
while 1<2
begin
print'Filename: '
fn=gets.chomp
file = fn+'.txt'
f = File.open file, 'r'
puts "MADE BY THE PEOPLE, FOR THE PEOPLE #madebylorax" #helped by lineone
puts ""
puts "--------------------------------------------------------"
puts ""
while line = f.gets
line = line.chomp.split(';')
email, password = line
HackEx.LoginDo(email, password) do |http, auth_token, user|
puts "Retrieving Info..."
puts''
user = HackEx::Request.Do(http, HackEx::Request.UserInfo(auth_token))['user']
bank = HackEx::Request.Do(http, HackEx::Request.UserBank(auth_token))['user_bank']
json = HackEx::Request.Do(http, HackEx::Request.UserSpam(auth_token))['spam']
cash_count=0
tot_count=0
json.each do |j|
earn_rate = j['earning_rate_hr']
total= j['total_earnings']
cash_count+=earn_rate.to_i
tot_count+=total.to_i
end
print "#{email}: current earnings: #{cash_count} per hour, Total earnings #{tot_count},"
userchecking = bank["checking"]
checking = userchecking.scan(/.{1,3}/).join(',')
puts " #{checking} BTC in Checking"
puts ""
puts "--------------------------------------------------------"
puts ""
sleep 1
end
end
rescue
puts"#{$!}"
end
end
Thats fine you can also calculate the total income of your farms by adding new variables at the top example a=0 then adding the number at the end a+=tot_count
This should help:
earning_rates = json.map{|e| e["earning_rate_hr"]}
puts "Earning rates per hour: #{earning_rates.join(" ")}"
puts "Sum of earning rates: #{earning_rates.map{|e| e.to_i}.inject{|sum, x| sum + x}}"

Recursion in Ruby isnt working like I think it should

I don't understand why this method isn't working. when I put in a value that should pass the if statement it doesn't work.
def getBase
puts "What is the base URL for the test?"
x = gets
if (x.include? 'http://') && ((x.split('.').at(x.split('.').length - 1).length) == 3)
return x
else
puts "That is in the incorrect format."
puts "Please format your url like this"
puts "http://example.com"
getBase
end
end
input 'http://test.com'
result: statement repeats and does not exit recursion
When you get input with gets it includes the newline \n at the end (from the user hitting return). So your x is actually "http://test.com\n".
To get rid of this use String#chomp:
x = gets.chomp
That should do it.
If the purpose is to enforce correct URL format and/or make sure it's an HTTP URL, why don't you use a tool designed to do that? Ruby's URI class is your friend:
require 'uri'
URI.parse('http://foo.bar').is_a?(URI::HTTP)
=> true
URI.parse('ftp://foo.bar').is_a?(URI::HTTP)
=> false
URI.parse('file://foo.bar').is_a?(URI::HTTP)
=> false
URI.parse('foo.bar').is_a?(URI::HTTP)
=> false
I'd write the code more like this:
require 'uri'
def get_base
loop do
puts "What is the base URL for the test?"
x = gets.chomp
begin
uri = URI.parse(x)
return uri.to_s if uri.is_a?(URI::HTTP)
rescue URI::InvalidURIError
end
puts "That is in the incorrect format."
puts "Please format your URL like this:"
puts
puts " http://example.com"
end
end
puts "Got: #{ get_base() }"

Resources