Python3, Variable Value change into class in a method call - python-3.6

I have the init_sale variable but when calling a method that has nothing to do with the variable, it changes the variable value
Class Code
def get(self, nro_order):
order = Order().get_by_order(nro_order)
if order is None:
nro_order)
)
return None
init_sale = self.get_init_sale(nro_order) #this change after call calculate sale
nationalized = self.get_nationalized(order)
data = {
'init_sale': init_sale,
'nationalized': nationalized,
'sale': self.calculate_sale(init_sale, nationalized)
}
return data
def calculate_sale(self, init_sale, nationalized):
sale = init_sale
for item in sale:
for nat in nationalized:
if item['detalle_pedido_factura'] == nat['detalle_pedido_factura']:
item['nro_cajas'] -= nat['nro_cajas']
return sale
init_sale before call calculate_sale:
[{'detalle_pedido_factura': 1164, 'cod_contable': '01011080050317010750', 'nro_cajas': 1145, 'costo_caja': 18.5}]
init_sale after call calculate_sale:
[{'detalle_pedido_factura': 1164, 'cod_contable': '01011080050317010750', 'nro_cajas': 0, 'costo_caja': 18.5}]
nro_cajas value change
Thanks

According to your code, your method calculate_sale is substracting nro_cajas to itself :
‘item['nro_cajas'] -= nat['nro_cajas']‘
When you did :
‘sale = init_sale‘
You did not create a new instance of your dict, you just point toward it thru the "sale" variable.
You should do :
’sale = init_sale.copy()’

im solved this problem, but i think it is not correct way
def calculate_sale(self, init_sale, nationalized):
sale = [] #create empty list
for itm in init_sale: #append items :(
sale.append({
'detalle_pedido_factura': itm['detalle_pedido_factura'],
'cod_contable': itm['cod_contable'],
'nro_cajas': itm['nro_cajas'],
'costo_caja': itm['costo_caja'],
})
for item in sale:
for nat in nationalized:
if item['detalle_pedido_factura'] == nat['detalle_pedido_factura']:
item['nro_cajas'] -= nat['nro_cajas']
return sale

Related

how would I delete item's in a dictionary within specific parameters?

for my code I want all numbers from a dictionary under 70 to be deleted, I'm unsure of how to specify this and I need it to also delete the associated name with that number as well, either that or only diplay numbers that are 70 or above.
Below is the code that I have in it's entirety:
name = []
number =[]
name_grade = {}
counter = 0
counter_bool= True
num_loop = True
while counter_bool:
stu = int(input("please enter the number of students: "))
if stu < 2:
print("value is too low, try again")
continue
else:
break
while counter != stu:
name_inp = str(input("Enter your name: "))
while num_loop:
number_inp = int(input("Enter your number: "))
if number_inp < 0 or number_inp > 100:
print("The value is too high or too low, please enter a number between 0 and 100.")
continue
else:
break
name_grade[name_inp] = number_inp
name.append(name_inp)
number.append(number_inp)
counter += 1
print(name_grade)
sorted_numbers = sorted(name_grade.items(), key= lambda x:x[1])
print(sorted_numbers)
if number > 70:
resorted_numbers = number < 70
print(resorted numbers)
how would I go about this?
Also if it's also not too much trouble could someone explain in detail about dictionary keys and how the lambda function I've used works? I got help but I would prefer to know the small details on how it's applied and formatted but don't worry if it's a pain to explain.
You can just iterate over the dictionary and filter for values less than 70:
resorted_numbers = {k:v for k,v in name_grade.items() if v<70}
dict.items method returns a list of key-value tuple pairs of a dictionary, so the lambda function is telling the sorted function to sort by the second element in each tuple.

How to calculate similarities between test and train documents

I'm trying to calculate similarities between test and train documents and label them. Here is the code but it doesn't work. I'd also appreciate if somebody could explain the idea.
def calculate_similarities(self, vecTestDoc, vectorsOfTrainDocs):
list_of_similarities = []
for vector in vectorsOfTrainDocs:
label = vectorsOfTrainDocs.key()
list_of_similarities += [(self.calculate_similarities(vector, vecTestDoc), label)]
return list_of_similarities
Here's the error:
File "..\classification.py", line 98, in calculate_similarities
label = vectorsOfTrainDocs.key()
AttributeError: 'list' object has no attribute 'key'
Edit: I've defined two more functions and have been working on a different solution. Here are they:
def cosine_similarity(self, weightedA, weightedB):
dotAB = dot(weightedA, weightedB)
normA = math.sqrt(dot(weightedA, weightedA))
normB = math.sqrt(dot(weightedB, weightedB))
return dotAB / (normA * normB)
def fit(self, doc_collection):
self.doc_collection = doc_collection
self.vectorsOfDoc_collection = [(doc, self.doc_collection.tfidf(doc.token_counts))
for doc in self.doc_collection.docid_to_doc.values()]
I believe something like this would work but there are still error messages... What should I change?
return [self.doc_collection.cosine_similarity(vecTestDoc) in vectorsOfTrainDocs]

RxJava - Count events on the fly

I would like to count objects passing from observable. I know there is a count operator but that can't be used for infinite streams because it waits for completition.
What I want is something like Value -> operator -> Pair(Int, Value). I know there could be a problem with int (or long) overflow and that is maybe a reason nothing like this exists but I still have feeling I've seen something like this before. One can implement this with scan operator but I thought there is a simpler way.
Output would be like:
Observable.just(Event1, Event2, Event3) -> (1, Event1), (2, Event2), (3, Event3)
You can solve your problem using the RxJava Scan method:
Observable.just("a", "b", "c")
.scan(new Pair<>(0, ""), (pair, s) -> new Pair<>(pair.first + 1, s))
.skip(1)
Pair<>(0, "") is your seed value
Lambda (pair, s) -> new Pair<>(pair.first + 1, s) takes the seed value and value emitted by original observable and then produces the next Pair value to be emitted and fed back into the lambda
Skip(1) is needed to avoid emitting the seed value
Count means a state change. So you can use a "stateful" map instead of an anonymous class.
ex:
class Mapper<T, R>(val mapper: (T) -> R) : Function<T, Pair<Int, R>> {
private var counter = 0
override fun apply(t: T): Pair<Int, R> {
return Pair(counter++, mapper(t))
//or ++counter if you want start from 1 instead of zero
}
}
//usage
val mapper = Mapper<String, String> { it.toUpperCase() }
Observable.just("a", "b", "c")
.map(mapper)
.subscribe {
Log.d("test logger", it.toString())
}

function variable does not live outside a for loop

I have a generic function in julia that the aim is to say if a member of a vector of
a given dimension is negative or not. After a few variations I have:
function any(vec)
dim = size(vec)
for i in 1:dim[2]
fflag = vec[1,i] < 0
println("Inside any, fflag = ", fflag)
if fflag == true
result = 0
println("blabla ", result)
break
else
result =1
println("blabla ", result)
continue
end
end
println("hey, what is result? ")
println(result)
return result
end
If I run a test I found the following result:
Inside any, fflag = false
blabla 1
Inside any, fflag = false
blabla 1
Inside any, fflag = false
blabla 1
hey, what is result?
result not defined
at In[7]:57
I don't know why the compiler says me that 'result' is not defined. I know the variable exist but why does not live outside the for loop?
The documentation on variable scoping clearly states that a for loop defines a new scope. This means result is going out of scope when execution leaves the for loop. Hence it is undefined when you call println(result)
Defining result in advance of the for loop should give the behaviour you are expecting:
function any(vec)
dim = size(vec)
result = -1
for i in 1:dim[2]
...
Or if you do not wish to assign a default value, and are sure the for loop will set its value, you can do:
function any(vec)
dim = size(vec)
local result
for i in 1:dim[2]
...
In the first example, if the for loop does not set a value, result will be -1.
In the the second example, not setting a value in the for loop will leave result undefined.

How to call a closure with multiple parameters from collect() method of a groovy collection?

Let's say I have a closure:
def increment = {value, step ->
value + step
}
Now I want to loop over every item of my integers collection, increment it with 5, and save new elements to a new collection:
def numbers = [1..10]
def biggerNumbers = numbers.collect {
it + 5
}
And now I want to achieve the same result but by means of using increment closure. How can I do this?
Should be something like this (wrong code below):
def biggerNumbers = numbers.collect increment(it, 5) //what's the correct name of 'it'??
The solution to your problem would be nesting your call of increment in a closure:
def biggerNumbers = numbers.collect {increment(it, 5)}
If you wanted to pass a premade closure to the collect you should have made it compatible with collect - accepting a single parameter that is:
def incrementByFive = {it + 5}
def biggerNumbers = numbers.collect incrementByFive
mojojojo has the right answer, but just thought I'd add that this looks like a good candidate for currying (specifically using rcurry)
If you have:
def increment = {value, step ->
value + step
}
You can then curry the right-hand parameter of this function with:
def incrementByFive = increment.rcurry 5
And then, you can do:
def numbers = 1..10
def biggerNumbers = numbers.collect incrementByFive
Just thought it might be of interest ;-)
The main issue is that [1..10] creates a List<IntRange> which you are trying to increment. You should collect on the IntRange directly (note the lack of brackets):
(1..10).collect { it + 5 }
Or with curry:
def sum = { a, b -> a + b }
(1..10).collect(sum.curry(5))

Resources