With the holidays coming up, my team is working on developing a script for our Shopify store that prevents our customers from using discount codes if they have one of the following in their cart : Donations, Items already on sale, and items that qualify for a F30 335i giveaway. Here is the code I currently have :
##disable discount codes##
error_message = 'Cannot use Discount. Reason(s) : '
marzano_donation_id = 6723597598805
marzano_donation = false
Input.cart.line_items.each do |line_item|
product = line_item.variant.product
puts product.id
if Input.cart.discount_code != nil
# only runs if customer has discount code
if product.id == marzano_donation_id
# marzano_donation = true
marzano_error = "Marzano's Donation in cart, "
error_message.concat(marzano_error)
# Input.cart.discount_code.reject({message: "1"})
end
end
end
list_of_invalid_vendors = []
vendor_message = "Invalid vendors in cart : #{list_of_invalid_vendors}"
contains_vendor = false
vendor_list = ["Evolution Racewerks", "Kies Giveaway Items", "Precision Raceworks"]
Input.cart.line_items.each do |line_item|
vendor = line_item.variant.product.vendor
if vendor_list.include? vendor
list_of_invalid_vendors.append(vendor)
if Input.cart.discount_code != nil
error_message.concat(vendor_message)
puts list_of_invalid_vendors
puts vendor_message
end
puts list_of_invalid_vendors
end
end
puts contains_vendor
contains_giveaway = false
Input.cart.line_items.each do |line_item|
product = line_item.variant.product
next unless product.tags.include?('Kies Giveaway Items')
# Input.cart.discount_code.reject({message: "3"})
# contains_giveaway = true
giveaway_error = " Cannot use discount code on Kies Giveaway Items, "
error_message.concat(giveaway_error)
end
puts contains_giveaway
puts "123"
if Input.cart.discount_code != nil
Input.cart.discount_code.reject({message: "#{error_message}"})
end
Output.cart = Input.cart
Currently with this output, I can get the error message I want -- but only when it is a string.
The last piece to my puzzle is needed to be able to display the invalid vendors that the customer has in their cart, shown here :
list_of_invalid_vendors = []
vendor_message = "Invalid vendors in cart : #{list_of_invalid_vendors}"
contains_vendor = false
vendor_list = ["Evolution Racewerks", "Kies Giveaway Items", "Precision Raceworks"]
Input.cart.line_items.each do |line_item|
vendor = line_item.variant.product.vendor
if vendor_list.include? vendor
list_of_invalid_vendors.append(vendor)
if Input.cart.discount_code != nil
error_message.concat(vendor_message)
puts list_of_invalid_vendors
puts vendor_message
end
puts list_of_invalid_vendors
end
end
What I would like to have is code that outputs : "Cannot use discount, Invalid vendors in cart : Evolution racewerks, Precision Raceworks"
But instead what I keep on getting is :
Cannot use Discount. Reason(s) : Invalid vendors in cart : []
So to clarify -- my initial issue was that the output I was receiving was the following : Cannot use Discount. Reason(s) : Invalid vendors in cart : [] -- when in reality what I needed to be displayed in the cart was : "Invalid vendors in cart : Evolution racewerks, Precision raceworks..." What I also wanted to avoid was the content of the array being displayed, as in -- Invalid vendors in cart : ["evolution racewerks', ...] -- SO upon further research, what I discovered was that my issue was in this line here :
vendor_message = "Invalid vendors in cart : #{list_of_invalid_vendors}"
Im not entirely sure why this wouldn't work, but when I printed out "list_of_invalid_vendors", it didn't return null, but when I printed out vendor_message, it did.
So for me to be able to take an array, append values to it, and create a clean looking sentence that was easy to read for my user, i wrote the following :
invalid_vendors = invalid_vendors.join(', ')
vendor_message = "Black Friday Vendors in Cart : #{invalid_vendors}, "
error_message.concat(vendor_message)
Related
I am using VBA Access to get data from Google Books for a library database. The code is based on that given in this stackoverflow question.
I am struggling for the right code to allow for a varying number of authors as the information is in a nested array. I would like all of the author names to appear in one TextBox.
I tried:
Form_AddAmendItems.AuthorTextBox.Value = Join(subitem("authors"), ",")
from the link above but that fails to find any result.
I think I need to use UBound and LBound to count the number of authors and then loop through and add each one. But I haven't been able to find an example of how to do that.
Currently as a workaround I can populate the AuthorTextBox with the names of up to 3 authors, which is enough for my needs. But if there are less than 3 authors the error handler message pops up because it hasn't been able to find the requested data.
I am using the VBA-JSON Converter from here.
This is the JSON I would like to parse (from here)
{
"kind": "books#volumes",
"totalItems": 1,
"items": [
{
"kind": "books#volume",
"id": "BT2CAz-EjvcC",
"etag": "6Z7JqyUtyJU",
"selfLink": "https://www.googleapis.com/books/v1/volumes/BT2CAz-EjvcC",
"volumeInfo": {
"title": "Collins Gem German Dictionary",
"subtitle": "German-English, English-German",
"authors": [
"Veronika Calderwood-Schnorr",
"Ute Nicol",
"Peter Terrell"
]
And this is my VBA code:
Private Sub FindBookDetailsButton_Click()
'Error handle for Null Strings
If IsNull(Me.ISBNTextBox) = True Then
MsgBox "Item ID not specified.", vbExclamation + vbOKOnly, "Error"
Exit Sub
End If
'Error message if there is no match
On Error GoTo ErrMsg
Dim http As Object, JSON As Object, i As Integer, subitem As Object
Dim ISBN As String
ISBN = CStr(Me.ISBNTextBox.Value)
Set http = CreateObject("MSXML2.XMLHTTP")
http.Open "GET", "https://www.googleapis.com/books/v1/volumes?q=isbn:" & ISBN, False
http.send
Set JSON = ParseJSON(http.responseText)
For Each item In JSON("items")
Set subitem = item("volumeInfo")
Form_AddAmendItems.TitleTextBox.Value = subitem("title")
Form_AddAmendItems.AuthorTextBox.Value = subitem("authors")(1)
Form_AddAmendItems.PublisherTextBox.Value = subitem("publisher")
'For multiple authors
Set subitem = item("volumeInfo")
If subitem.Exists("authors") Then
For Each item2 In subitem("authors")
Form_AddAmendItems.AuthorTextBox.Value = subitem("authors")(1) & ", " & subitem("authors")(2)
Next
For Each item3 In subitem("authors")
Form_AddAmendItems.AuthorTextBox.Value = subitem("authors")(1) & ", " & subitem("authors")(2) & ", " & subitem("authors")(3)
Next
End If
Next
'To end with success
MsgBox ("Process complete"), vbInformation
Exit Sub
'To end with an error message
ErrMsg:
MsgBox ("No match obtained"), vbCritical
End Sub
An array or collection or dictionary can be looped without knowing that object's limits. So if subitem("authors") is one of those object types, your code could be something like (essentially the code shown in accepted answer for the SO link in your question):
Set subitem = item("volumeInfo")
Form_AddAmendItems.TitleTextBox.Value = subitem("title")
Form_AddAmendItems.PublisherTextBox.Value = subitem("publisher")
If subitem.Exists("authors") Then
For Each item2 In subitem("authors")
sA = sA & item2 & ","
Next
sA = Left(sA, Len(sA) - 1) 'remove trailing comma
If sA <> "" Then Form_AddAmendItems.AuthorTextBox.Value = sA
End If
I discovered that elements in the ISBN download aren't always the same. As an example, with ISBN 0-575-05577-4 the publisher is not provided even though publishedDate is. Might use an If Then condition for each element you want to explicitly address. As a side note, found it interesting that the co-author for that book was not included.
Hi could some one please help. I am very new to Python and need help with something I am creating. I would like to to print six statements and then ask the user to enter their answer. The answer needs to be ie. S2, S10 etc. etc. If not true would like it to loop again until correct input has been given.
Please see below:
print("S0 = Initail Issue ")
print("S2 = Information Issue ")
print("S3 = Internal Review & Comment Issue ")
print("S4 = Suitable for Construction in DPP Stage only ")
print("S10 = Construction Issue")
print("CR = Construction Record (As Built)Issue\n")
Initial = "S0"
Information = "S2"
Review = "S3"
DPP = "S4"
Construction = "S10"
As_built = "CR"
Suitability = (input("Look above on the list of suitability is it?\n ").upper())
Suit = {"Initial", "Information", "Review", "DPP", "Construction", "As_built"}
while True:
Suit = Suitability
if Suit == Suitability:
break
else:
print("is not the correct information! ")
Suitability = (input("Look above on the list of suitability is it?\n ").upper())
print("S0 = Initial Issue ")
print("S2 = Information Issue ")
print("S3 = Internal Review & Comment Issue ")
print("S4 = Suitable for Construction in DPP Stage only ")
print("S10 = Construction Issue")
print("CR = Construction Record (As Built) Issue\n")
Initial = "S0"
Information = "S2"
Review = "S3"
DPP = "S4"
Construction = "S10"
As_built = "CR"
validOptions = [Initial, Information, Review, DPP, Construction, As_built]
while True:
Suitability = (input("Look above on the list of suitability is it?\n ").upper())
if Suitability in validOptions:
break
print("is not the correct information!")
print("You entered", Suitability)
I used if item in container syntax to validate the input by checking to see if the provided input is in a list of valid options.
I also restructured your loop so that you only have to express the input prompt once in your code.
I'm trying to set up a program to help me take care of grading for students in a class. I've set it up to make a class of student then to read in from the file (something I'm not very familiar with in Ruby) via an array. My programming experience is in java so if there are errors that can be explained by that I apologize. Thank you in advance for your help.
class Student
def initialize(str_LastName, str_FirstName, arr_Score)
#str_LastName = str_LastName
#str_FirstName = str_FirstName
#arr_Score = arr_Score
str_Grade = ""
int_OutOf = 415
end
def get_LastName
str_LastName
end
def get_FirstName
str_FirstName
end
def get_Grade
str_Grade
end
def set_TotalScore()
sum = 0
arr_Score.each do |item|
sum += item
end
arr_Score[12] = sum
end
def set_Grade
if arr_Score[12]/int_OutOf >= 0.9
str_Grade = "A"
elsif arr_Score[12]/int_OutOf >= 0.8
str_Grade = "B"
elsif arr_Score[12]/int_OutOf >= 0.7
str_Grade = "C"
elsif arr_Score[12]/int_OutOf >= 0.6
str_Grade = "D"
else
str_Grade = "F"
end
end
end
def main
file_name = "Grades"
arr_students = Array.new(31)
arr_scores = Array.new(12)
int_i = 0
file_io = open(file_name).readlines.each do |line|
array = line.split(",").map(&:strip)
student = Student.new(array[0],array[1],array[2..-2]) #the final element in the array is for the final score
arr_students[int_i] = student
puts "read #{arr_students[int_i]}"
end
file_name = "Graded"
file_io = open(file_name,"a+")
arr_students.each do |student|
set_TotalScore
set_Grade
file.io_write(student)
puts "write #{student}"
end
end
main if __FILE__==$0
Here is my run at it. I tried to stay true in general to the original intent of your code while introducing more Rubyish ways of doing things.
class Student
def initialize(firstname, lastname, *scores)
#firstname, #lastname, #scores = firstname, lastname, scores
end
def total_score
#scores.map(&:to_i).inject(:+)
end
def grade
raise "TOO HIGH!" if total_score > MAX_SCORE
case total_score / MAX_SCORE
when 0.9..1.0; "A"
when 0.8...0.9; "B"
when 0.7...0.8; "C"
when 0.6...0.7; "D"
else "F"
end
end
def to_s
"#{#lastname}, #{#firstname}: #{total_score}, #{grade}"
end
end
MAX_SCORE = 415.0
DATA.each_line do |line|
arr = line.split(",").map(&:strip)
student = Student.new *arr
puts student
end
__END__
Herb,Goldberg,22,99,44,22,88,88
Mark,Sullivan,77,88,88,44,33
You can read and write to files like this(not tested):
outfile = File.open("Graded", "a+")
File.open("Grades").each_line do |line|
...
outfile.puts student
end
outfile.close
We can not easily reproduce your code because you open a file called "Grades" and we do not have or know of its content.
You should also add some code to first check whether your file exists, before continuing - right now your script exits with a Errno::ENOENT.
I would also suggest putting the logic in main into your class instead - let your class handle everything.
In the part:
if __FILE__ == $PROGRAM_NAME
end
You can then simply initialize your class with a simple call such as:
Foobar.new(ARGV)
You described the "Grades" file but I did not understand what you wrote - it would be easier if you could link in to a sample, like via a pastie or gist, then link it in; and to also say what the part is that is not working, which is also unclear.
The style issues are secondary, I consider your code ok - the other poster here does not.
You should go through codecademy to get your ruby syntax down.
To access your initialized instance variables (#str_LastName (which should be #last_name), etc) you need to use "attr_reader :str_LastName", preferably at the top of the class. That'll definite you getter (setter is attr_writer, both is attr_accessor).
You can also do a sum on an array like this: [1,4,6,7].inject(:+).
Does Java not allow case statements? You should use that in set_grade. You also don't need to initialize str_Grade. In set grade, you could do #grade_letter ||= "A", and then calling set_grade will return that value on each call.
I didn't look through your main method. It's ugly though. Ruby methods probably shouldn't be more than 5 lines long.
I should create a search page in which i have to save in an Array all the results of the searching. I had two problems:
1) I used the following statement:
Company.joins(:references).where(sql_string)
that returns an ActiveRecord:Relation and it's not good for me cause i have to display these results in the index action , in which i use an each statement. So , to overcame this problem i used the to_a.
I checked the .class of my variable and with the to_a it passed from ActiveRecord:Relation to Array. So , it seems that this solve the problem.
Company.joins(:references).where(sql_string).to_a
2) Now, i have to pass this variable (Array) into my index action.
I executed the search in the action called search:
def search
...
#companies = Company.joins(:references).where(sql_string).to_a
end
Now, i want to pass this to index:
def index
#companies ||= Company.all
end
I used #companies ||= Company.all cause i think that the #companies is and istance variable and it should be available in all the actions of the class. Isn't it? By the way, it doesn't workl. I mean , the results are not shared through the two methods.
Also , in the search action i don't know how to call index action. I used the redirect_to but this bring me to another problem.
def search
...
#companies = Company.joins(:references).where(sql_string).to_a
redirect_to companies_index_path
end
The second time i call the search action it brings me into the index action.As i insered the searching value. At really he still had the past searching in memory, and i don't want this behavior.
So , in other words, i want to:
passing #companies searching result to index action.
avoid the loop between search-index. So in every new request resets
the old searching.
i want to know if it's correct the casting with the to_a to bring
an ActiveRecord:Relation to Array.
Thank You.
EDIT:
def search
stringa_sql = ""
ragione_sociale = ""
riferimento = ""
note = ""
min_date = ""
max_date = ""
company_type = ""
sector = ""
country = ""
certification = ""
contact = ""
state = ""
manage = ""
consultation = ""
formation = ""
software = ""
if params[:ragione_sociale]
ragione_sociale = params[:ragione_sociale]
stringa_sql = "ragione_sociale like "+"'%"+ragione_sociale+"%'"
end
if params[:riferimento]
riferimento = params[:riferimento]
stringa_sql += " AND nome like "+"'%"+riferimento+"%'"
end
if params[:note]
note = params[:note]
stringa_sql += " AND note like "+"'%"+note+"%'"
end
if params[:min_date] && params[:min_date]!= ""
if params[:max_date] && params[:max_date]!= ""
min_date = params[:min_date]
max_date = params[:max_date]
stringa_sql += " AND richiamare >="+min_date+" AND richiamare <="+max_date
end
end
if params[:company_type] #se inviamo la richesta senza scrivere params[:category] viene passato vuoto
if params[:company_type][:id] != ""
company_type = params[:company_type][:id]
stringa_sql += " AND id_forma_giuridica = "+company_type
end
end
if params[:sector]
if params[:sector][:id] != ""
sector = params[:sector][:id]
stringa_sql += " AND id_settore = "+sector
end
end
if params[:country]
if params[:country][:id] != ""
country = params[:country][:id]
stringa_sql += " AND id_provincia = "+country
end
end
if params[:certification]
if params[:certification][:id] != ""
certification = params[:certification][:id]
stringa_sql += " AND id_certificazione = "+certification
end
end
if params[:contact]
if params[:contact][:id] != ""
contact = params[:contact][:id]
stringa_sql += " AND id_contattato = "+contact
end
end
if params[:state]
if params[:state][:id] != ""
state = params[:state][:id]
stringa_sql += " AND id_stato = "+state
end
end
if params[:manage]
if params[:manage][:id] != ""
manage = params[:manage][:id]
stringa_sql += " AND id_gestito = "+manage
end
end
if params[:consultation]
if params[:consultation][:id] != ""
consultation = params[:consultation][:id]
stringa_sql += " AND id_consulenza = "+consultation
end
end
if params[:formation]
if params[:formation][:id] != ""
formation = params[:formation][:id]
#formazione DA METTERE
end
end
if params[:software]
if params[:software][:id] != ""
software = params[:software][:id]
stringa_sql += " AND id_software = "+software
end
end
#companies = Company.search(stringa_sql).to_a
if not #companies.empty?
redirect_to companies_index_path
end
end
index:
def index
#companies ||= Company.all
end
I used #companies ||= Company.all cause i think that the #companies
is and istance variable and it should be available in all the actions
of the class. Isn't it?
Not really, it depends on from where you want to access the #companies instance variable. e.g. from which view, you need #companies instance variable in the corresponding action method of the controller.
The second time i call the search action it brings me into the index
action
You are using redirect_to companies_index_path in your search method which brings you to the index action.
To implement search in your application, you can follow this somewhat standard process:
In your application_controller.rb which will have the #search_query.
# Returns string
def search_query
#search_query ||= params[:query] || params[:search]
end
Then, in your searches_controller.rb, you can have:
def search
# in the method build your search results based on
# search_query param
#search_results = Company.joins(:references).where(sql_string(search_query)).to_a
end
In your routes.rb, you can have:
get '/search(/:query)' => 'searches#search', query: /.+/, as: 'search'
Which will take you to the searches_controller's search action where you are building the search results #search_results.
Finally, you need to have a app/views/searches/search.html.erb view file where you have access to your #search_results instance variable and you can just loop through them and display them in this view.
Answers to your last 3 questions:
passing #companies searching result to index action.
avoid the loop between search-index. So in every new request resets
the old searching.
You can overcome these problems by following the request/response flow that I have mentioned above. You should not share your index view with your search and you should not have any loop between search and index. Both of them are separate actions of the controller and can be handled separately as I showed above.
i want to know if it's correct the casting with the to_a to bring an
ActiveRecord:Relation to Array.
You can do that if you want. But, you don't really need it in this use case. You can store the ActiveRecord:Relation in your search_results and when you access this instance variable from inside your search.html.erb view, you can easily loop through using a .each do block. So, you don't have to worry about ActiveRecord:Relation and Array.
So I am using a gift certificate module with satchmo store and in order to send multiple gift certificate codes equal to the number of items purchased I need to add a loop doing
"while quantity is greater than zero loop"
Here is the code, the loop is being added to right before "price=order_item.unit_price"
def order_success(self, order,
order_item):
log.debug("Order success called, creating gift certs on order:
%s", order)
message = ""
email = ""
for detl in order_item.orderitemdetail_set.all():
if detl.name == "email":
email = detl.value
elif detl.name == "message":
message = detl.value
price=order_item.unit_price
log.debug("Creating gc for %s", price)
gc = GiftCertificate(
order = order,
start_balance= price,
purchased_by = order.contact,
valid=True,
message=message,
recipient_email=email
)
gc.save()
I am not sure I understand the question, but maybe something like
for ix in range(0, order_item.quantity):
... do stuff
might do the trick. You don't have to use the ix anywhere inside the loop, it is just (arguably) the standard way to do something n times in Python.