问:
OpenCV - detect components of certain width
I have an image with detected components. From this I need to detect components that form "polyline" of certain width (white and red in the image below).

What algorithm is best for this in OpenCV? I have tried separate all components one by one and use morphological operations but that was quite slow and not entirely accurate.

Note: the image below is downsampled. Original image has resolution 8K and border thickness is approx. 30-40px.

答:
I like your question - it is kind of like granulometry of lines instead of grains.

My approach is to find the unique colours in your image and then, for each colour:

isolate that colour as white on black

repeatedly erode by 3 pixels till nothing is left

Note that 20-30% of the code below is just for debug and explanation, and also that it could be speeded up with multi-processing and a little tweaking.

```<code>#!/usr/bin/env python3

import cv2
import numpy as np
from skimage.morphology import medial_axis, erosion, disk

def getColoursAndCounts(im):
   """Returns list of unique colours in an image and their counts."""

   # Make a single 24-bit number for each pixel - it's faster
   f = np.dot(im.astype(np.uint32), [1,256,65536])
   # Count unique colours in image and how often they occur
   colours, counts = np.unique(f, return_counts=1)
   # Convert found colours back from 24-bit number to BGR
   return np.dstack((colours&255,(colours>>8)&255,colours>>16)).reshape((-1,3)), counts

if __name__ == "__main__":

   # Load image and get colours present and their counts
   im = cv2.imread('classes_fs.png',cv2.IMREAD_COLOR)
   colours, counts = getColoursAndCounts(im)

   # Iterate over unique colours/classes - this could easily be multi-processed
   for index, colour in enumerate(colours):
      b, g, r = colour
      count = counts[index]
      print(f'DEBUG: Processing class {index}, colour ({b},{g},{r}), area {count}')

      # Generate this class in white on a black background for processing
      m = np.where(np.all(im==[colour], axis=-1), 255, 0).astype(np.uint8)
      # Create debug image - can be omitted
      cv2.imwrite(f'class-{index}.png', m)

      # DEBUG only - show progression of erosion
      out = m.copy()

      # You could trim the excess black around the shape here to speed up morphology

      # Erode, repeatedly with disk of radius 3 to determine line width
      radius = 3
      selem = disk(radius)
      for j in range(1,7):
         # Erode again, see what's left
         m  = erosion(m,selem)
         c = cv2.countNonZero(m)
         percRem = int(c*100/count)
         print(f'   Iteration: {j}, nonZero: {c}, %remaining: {percRem}')
         # DEBUG only
         out = np.hstack((out, m))

         if c==0:
            break
      # DEBUG only
      cv2.imwrite(f'erosion-{index}.png', out)
</code>```

So, the 35 unique colours in your image give rise to these classes once isolated:

Here is the output:

```<code>DEBUG: Processing class 0, colour (0,0,0), area 629800
   Iteration: 1, nonZero: 390312, %remaining: 61
   Iteration: 2, nonZero: 206418, %remaining: 32
   Iteration: 3, nonZero: 123643, %remaining: 19
   Iteration: 4, nonZero: 73434, %remaining: 11
   Iteration: 5, nonZero: 40059, %remaining: 6
   Iteration: 6, nonZero: 21975, %remaining: 3
DEBUG: Processing class 1, colour (10,14,0), area 5700
   Iteration: 1, nonZero: 2024, %remaining: 35
   Iteration: 2, nonZero: 38, %remaining: 0
   Iteration: 3, nonZero: 3, %remaining: 0
   Iteration: 4, nonZero: 0, %remaining: 0
...
...
DEBUG: Processing class 22, colour (174,41,180), area 3600
   Iteration: 1, nonZero: 1501, %remaining: 41
   Iteration: 2, nonZero: 222, %remaining: 6
   Iteration: 3, nonZero: 17, %remaining: 0
   Iteration: 4, nonZero: 0, %remaining: 0
DEBUG: Processing class 23, colour (241,11,185), area 200
   Iteration: 1, nonZero: 56, %remaining: 28
   Iteration: 2, nonZero: 0, %remaining: 0
DEBUG: Processing class 24, colour (247,23,185), area 44800
   Iteration: 1, nonZero: 38666, %remaining: 86
   Iteration: 2, nonZero: 32982, %remaining: 73
   Iteration: 3, nonZero: 27904, %remaining: 62
   Iteration: 4, nonZero: 23364, %remaining: 52
   Iteration: 5, nonZero: 19267, %remaining: 43
   Iteration: 6, nonZero: 15718, %remaining: 35
DEBUG: Processing class 25, colour (165,142,185), area 33800
   Iteration: 1, nonZero: 30506, %remaining: 90
   Iteration: 2, nonZero: 27554, %remaining: 81
   Iteration: 3, nonZero: 24970, %remaining: 73
   Iteration: 4, nonZero: 22603, %remaining: 66
   Iteration: 5, nonZero: 20351, %remaining: 60
   Iteration: 6, nonZero: 18206, %remaining: 53
DEBUG: Processing class 26, colour (26,147,198), area 2100
   Iteration: 1, nonZero: 913, %remaining: 43
   Iteration: 2, nonZero: 152, %remaining: 7
   Iteration: 3, nonZero: 12, %remaining: 0
   Iteration: 4, nonZero: 0, %remaining: 0
DEBUG: Processing class 27, colour (190,39,199), area 18500
   Iteration: 1, nonZero: 6265, %remaining: 33
   Iteration: 2, nonZero: 0, %remaining: 0
DEBUG: Processing class 28, colour (149,210,201), area 2200
   Iteration: 1, nonZero: 598, %remaining: 27
   Iteration: 2, nonZero: 0, %remaining: 0
DEBUG: Processing class 29, colour (188,169,216), area 10700
   Iteration: 1, nonZero: 9643, %remaining: 90
   Iteration: 2, nonZero: 8664, %remaining: 80
   Iteration: 3, nonZero: 7763, %remaining: 72
   Iteration: 4, nonZero: 6932, %remaining: 64
   Iteration: 5, nonZero: 6169, %remaining: 57
   Iteration: 6, nonZero: 5460, %remaining: 51
DEBUG: Processing class 30, colour (100,126,217), area 5624300
   Iteration: 1, nonZero: 5565713, %remaining: 98
   Iteration: 2, nonZero: 5511150, %remaining: 97
   Iteration: 3, nonZero: 5464286, %remaining: 97
   Iteration: 4, nonZero: 5420125, %remaining: 96
   Iteration: 5, nonZero: 5377851, %remaining: 95
   Iteration: 6, nonZero: 5337091, %remaining: 94
DEBUG: Processing class 31, colour (68,238,237), area 2100
   Iteration: 1, nonZero: 1446, %remaining: 68
   Iteration: 2, nonZero: 922, %remaining: 43
   Iteration: 3, nonZero: 589, %remaining: 28
   Iteration: 4, nonZero: 336, %remaining: 16
   Iteration: 5, nonZero: 151, %remaining: 7
   Iteration: 6, nonZero: 38, %remaining: 1
DEBUG: Processing class 32, colour (131,228,240), area 4000
   Iteration: 1, nonZero: 3358, %remaining: 83
   Iteration: 2, nonZero: 2788, %remaining: 69
   Iteration: 3, nonZero: 2290, %remaining: 57
   Iteration: 4, nonZero: 1866, %remaining: 46
   Iteration: 5, nonZero: 1490, %remaining: 37
   Iteration: 6, nonZero: 1154, %remaining: 28
DEBUG: Processing class 33, colour (0,0,255), area 8500
   Iteration: 1, nonZero: 6046, %remaining: 71
   Iteration: 2, nonZero: 3906, %remaining: 45
   Iteration: 3, nonZero: 2350, %remaining: 27
   Iteration: 4, nonZero: 1119, %remaining: 13
   Iteration: 5, nonZero: 194, %remaining: 2
   Iteration: 6, nonZero: 18, %remaining: 0
DEBUG: Processing class 34, colour (255,255,255), area 154300
   Iteration: 1, nonZero: 117393, %remaining: 76
   Iteration: 2, nonZero: 82930, %remaining: 53
   Iteration: 3, nonZero: 51625, %remaining: 33
   Iteration: 4, nonZero: 24842, %remaining: 16
   Iteration: 5, nonZero: 6967, %remaining: 4
   Iteration: 6, nonZero: 2020, %remaining: 1
</code>```

If we look at class 34 - the one you are interested in. The successive erosions look like this - you can see the shape disappearing completely by a radius of around 15 pixels, which corresponds to losing 15 pixels on the left and 15 pixels on the right of your 30 pixel wide shape:

If you plot the percentage of pixels remaining after each successive erosion, you can easily see the difference between class 34 where it goes to zero after 5-6 erosions of 3 pixels each (i.e. 15-18 pixels) and class 25 where it doesn't:

Notes:

For anyone wishing to run my code, note that I up-scaled the input image (nearest-neighbour resampling) to 10x its current size with ImageMagick:

```<code>magick classes.png -scale 1000%x classes_fs.png
</code>```

Body:
I like your question - it is kind of like granulometry of lines instead of grains.

My approach is to find the unique colours in your image and then, for each colour:

isolate that colour as white on black

repeatedly erode by 3 pixels till nothing is left

Note that 20-30% of the code below is just for debug and explanation, and also that it could be speeded up with multi-processing and a little tweaking.

#!/usr/bin/env python3

import cv2
import numpy as np
from skimage.morphology import medial_axis, erosion, disk

def getColoursAndCounts(im):
   """Returns list of unique colours in an image and their counts."""

   # Make a single 24-bit number for each pixel - it's faster
   f = np.dot(im.astype(np.uint32), [1,256,65536])
   # Count unique colours in image and how often they occur
   colours, counts = np.unique(f, return_counts=1)
   # Convert found colours back from 24-bit number to BGR
   return np.dstack((colours&255,(colours>>8)&255,colours>>16)).reshape((-1,3)), counts

if __name__ == "__main__":

   # Load image and get colours present and their counts
   im = cv2.imread('classes_fs.png',cv2.IMREAD_COLOR)
   colours, counts = getColoursAndCounts(im)

   # Iterate over unique colours/classes - this could easily be multi-processed
   for index, colour in enumerate(colours):
      b, g, r = colour
      count = counts[index]
      print(f'DEBUG: Processing class {index}, colour ({b},{g},{r}), area {count}')

      # Generate this class in white on a black background for processing
      m = np.where(np.all(im==[colour], axis=-1), 255, 0).astype(np.uint8)
      # Create debug image - can be omitted
      cv2.imwrite(f'class-{index}.png', m)

      # DEBUG only - show progression of erosion
      out = m.copy()

      # You could trim the excess black around the shape here to speed up morphology

      # Erode, repeatedly with disk of radius 3 to determine line width
      radius = 3
      selem = disk(radius)
      for j in range(1,7):
         # Erode again, see what's left
         m  = erosion(m,selem)
         c = cv2.countNonZero(m)
         percRem = int(c*100/count)
         print(f'   Iteration: {j}, nonZero: {c}, %remaining: {percRem}')
         # DEBUG only
         out = np.hstack((out, m))

         if c==0:
            break
      # DEBUG only
      cv2.imwrite(f'erosion-{index}.png', out)

So, the 35 unique colours in your image give rise to these classes once isolated:

Here is the output:

DEBUG: Processing class 0, colour (0,0,0), area 629800
   Iteration: 1, nonZero: 390312, %remaining: 61
   Iteration: 2, nonZero: 206418, %remaining: 32
   Iteration: 3, nonZero: 123643, %remaining: 19
   Iteration: 4, nonZero: 73434, %remaining: 11
   Iteration: 5, nonZero: 40059, %remaining: 6
   Iteration: 6, nonZero: 21975, %remaining: 3
DEBUG: Processing class 1, colour (10,14,0), area 5700
   Iteration: 1, nonZero: 2024, %remaining: 35
   Iteration: 2, nonZero: 38, %remaining: 0
   Iteration: 3, nonZero: 3, %remaining: 0
   Iteration: 4, nonZero: 0, %remaining: 0
...
...
DEBUG: Processing class 22, colour (174,41,180), area 3600
   Iteration: 1, nonZero: 1501, %remaining: 41
   Iteration: 2, nonZero: 222, %remaining: 6
   Iteration: 3, nonZero: 17, %remaining: 0
   Iteration: 4, nonZero: 0, %remaining: 0
DEBUG: Processing class 23, colour (241,11,185), area 200
   Iteration: 1, nonZero: 56, %remaining: 28
   Iteration: 2, nonZero: 0, %remaining: 0
DEBUG: Processing class 24, colour (247,23,185), area 44800
   Iteration: 1, nonZero: 38666, %remaining: 86
   Iteration: 2, nonZero: 32982, %remaining: 73
   Iteration: 3, nonZero: 27904, %remaining: 62
   Iteration: 4, nonZero: 23364, %remaining: 52
   Iteration: 5, nonZero: 19267, %remaining: 43
   Iteration: 6, nonZero: 15718, %remaining: 35
DEBUG: Processing class 25, colour (165,142,185), area 33800
   Iteration: 1, nonZero: 30506, %remaining: 90
   Iteration: 2, nonZero: 27554, %remaining: 81
   Iteration: 3, nonZero: 24970, %remaining: 73
   Iteration: 4, nonZero: 22603, %remaining: 66
   Iteration: 5, nonZero: 20351, %remaining: 60
   Iteration: 6, nonZero: 18206, %remaining: 53
DEBUG: Processing class 26, colour (26,147,198), area 2100
   Iteration: 1, nonZero: 913, %remaining: 43
   Iteration: 2, nonZero: 152, %remaining: 7
   Iteration: 3, nonZero: 12, %remaining: 0
   Iteration: 4, nonZero: 0, %remaining: 0
DEBUG: Processing class 27, colour (190,39,199), area 18500
   Iteration: 1, nonZero: 6265, %remaining: 33
   Iteration: 2, nonZero: 0, %remaining: 0
DEBUG: Processing class 28, colour (149,210,201), area 2200
   Iteration: 1, nonZero: 598, %remaining: 27
   Iteration: 2, nonZero: 0, %remaining: 0
DEBUG: Processing class 29, colour (188,169,216), area 10700
   Iteration: 1, nonZero: 9643, %remaining: 90
   Iteration: 2, nonZero: 8664, %remaining: 80
   Iteration: 3, nonZero: 7763, %remaining: 72
   Iteration: 4, nonZero: 6932, %remaining: 64
   Iteration: 5, nonZero: 6169, %remaining: 57
   Iteration: 6, nonZero: 5460, %remaining: 51
DEBUG: Processing class 30, colour (100,126,217), area 5624300
   Iteration: 1, nonZero: 5565713, %remaining: 98
   Iteration: 2, nonZero: 5511150, %remaining: 97
   Iteration: 3, nonZero: 5464286, %remaining: 97
   Iteration: 4, nonZero: 5420125, %remaining: 96
   Iteration: 5, nonZero: 5377851, %remaining: 95
   Iteration: 6, nonZero: 5337091, %remaining: 94
DEBUG: Processing class 31, colour (68,238,237), area 2100
   Iteration: 1, nonZero: 1446, %remaining: 68
   Iteration: 2, nonZero: 922, %remaining: 43
   Iteration: 3, nonZero: 589, %remaining: 28
   Iteration: 4, nonZero: 336, %remaining: 16
   Iteration: 5, nonZero: 151, %remaining: 7
   Iteration: 6, nonZero: 38, %remaining: 1
DEBUG: Processing class 32, colour (131,228,240), area 4000
   Iteration: 1, nonZero: 3358, %remaining: 83
   Iteration: 2, nonZero: 2788, %remaining: 69
   Iteration: 3, nonZero: 2290, %remaining: 57
   Iteration: 4, nonZero: 1866, %remaining: 46
   Iteration: 5, nonZero: 1490, %remaining: 37
   Iteration: 6, nonZero: 1154, %remaining: 28
DEBUG: Processing class 33, colour (0,0,255), area 8500
   Iteration: 1, nonZero: 6046, %remaining: 71
   Iteration: 2, nonZero: 3906, %remaining: 45
   Iteration: 3, nonZero: 2350, %remaining: 27
   Iteration: 4, nonZero: 1119, %remaining: 13
   Iteration: 5, nonZero: 194, %remaining: 2
   Iteration: 6, nonZero: 18, %remaining: 0
DEBUG: Processing class 34, colour (255,255,255), area 154300
   Iteration: 1, nonZero: 117393, %remaining: 76
   Iteration: 2, nonZero: 82930, %remaining: 53
   Iteration: 3, nonZero: 51625, %remaining: 33
   Iteration: 4, nonZero: 24842, %remaining: 16
   Iteration: 5, nonZero: 6967, %remaining: 4
   Iteration: 6, nonZero: 2020, %remaining: 1

If we look at class 34 - the one you are interested in. The successive erosions look like this - you can see the shape disappearing completely by a radius of around 15 pixels, which corresponds to losing 15 pixels on the left and 15 pixels on the right of your 30 pixel wide shape:

If you plot the percentage of pixels remaining after each successive erosion, you can easily see the difference between class 34 where it goes to zero after 5-6 erosions of 3 pixels each (i.e. 15-18 pixels) and class 25 where it doesn't:

Notes:

For anyone wishing to run my code, note that I up-scaled the input image (nearest-neighbour resampling) to 10x its current size with ImageMagick:

magick classes.png -scale 1000%x classes_fs.png


来源: stackexchange

问:
How to stop BaseHTTPServer.serve_forever() in a BaseHTTPRequestHandler subclass?
I am running my HTTPServer in a separate thread (using the threading module which has no way to stop threads...) and want to stop serving requests when the main thread also shuts down.

The Python documentation states that BaseHTTPServer.HTTPServer is a subclass of SocketServer.TCPServer, which supports a shutdown method, but it is missing in HTTPServer.

The whole BaseHTTPServer module has very little documentation :(

答:
```<code>import http.server
import socketserver
import socket as sck
import os
import threading

class myserver:
    def __init__(self, PORT, LOCATION):
        self.thrd = threading.Thread(None, self.run)
        self.Directory = LOCATION
        self.Port = PORT
        hostname = sck.gethostname()
        ip_address = sck.gethostbyname(hostname)
        self.url = 'http://' + ip_address + ':' + str(self.Port)
        Handler = http.server.SimpleHTTPRequestHandler
        self.httpd = socketserver.TCPServer(("", PORT), Handler)
        print('Object created, use the start() method to launch the server')
    def run(self):
        print('listening on: ' + self.url )
        os.chdir(self.Directory)
        print('myserver object started')
        print('Use the objects stop() method to stop the server')
        self.httpd.serve_forever()
        print('Quit handling')

        print('Sever stopped')
        print('Port ' + str(self.Port) + ' should be available again.')

    def stop(self):
        print('Stopping server')
        self.httpd.shutdown()
        self.httpd.server_close()
        print('Need just one more request before shutting down'

    def start(self):
        self.thrd.start()

def help():
    helpmsg = '''Create a new server-object by initialising
NewServer = webserver3.myserver(Port_number, Directory_String)
Then start it using NewServer.start() function
Stop it using NewServer.stop()'''
    print(helpmsg)
</code>```

Not a experience python programmer, just wanting to share my comprehensive solution. Mostly based on snippets here and there. I usually import this script in my console and it allows me to set up multiple servers for different locations using their specific ports, sharing my content with other devices on the network.

OwnerDisplayName: Daren Thomas

ContentLicense: CC BY-SA 3.0

Body:
import http.server
import socketserver
import socket as sck
import os
import threading

class myserver:
    def __init__(self, PORT, LOCATION):
        self.thrd = threading.Thread(None, self.run)
        self.Directory = LOCATION
        self.Port = PORT
        hostname = sck.gethostname()
        ip_address = sck.gethostbyname(hostname)
        self.url = 'http://' + ip_address + ':' + str(self.Port)
        Handler = http.server.SimpleHTTPRequestHandler
        self.httpd = socketserver.TCPServer(("", PORT), Handler)
        print('Object created, use the start() method to launch the server')
    def run(self):
        print('listening on: ' + self.url )
        os.chdir(self.Directory)
        print('myserver object started')
        print('Use the objects stop() method to stop the server')
        self.httpd.serve_forever()
        print('Quit handling')

        print('Sever stopped')
        print('Port ' + str(self.Port) + ' should be available again.')

    def stop(self):
        print('Stopping server')
        self.httpd.shutdown()
        self.httpd.server_close()
        print('Need just one more request before shutting down'

    def start(self):
        self.thrd.start()

def help():
    helpmsg = '''Create a new server-object by initialising
NewServer = webserver3.myserver(Port_number, Directory_String)
Then start it using NewServer.start() function
Stop it using NewServer.stop()'''
    print(helpmsg)

Not a experience python programmer, just wanting to share my comprehensive solution. Mostly based on snippets here and there. I usually import this script in my console and it allows me to set up multiple servers for different locations using their specific ports, sharing my content with other devices on the network.

ContentLicense: CC BY-SA 4.0


问:
aspNetHidden div not being served depending on client
I am developing a C# app that gets web pages and processes their contents line by line. To do this, I use the HttpClient class, and read the page contents through ReadAsStreamAsync(). Then I read the stream into a line array and iterate over it. So far so good.

However, the HTML that I obtain with this method is not identical to the HTML that I observe if I navigate to the web page using Chrome or Edge and use View Source to get to the HTML. In particular, the __VIEWSTATE and __VIEWSTATEGENERATOR hidden input elements are surrounded by div elements with class="aspNetHidden" when I use the browser, but not when I get the HTML programmatically. This ruins my line tracking logic as there are extra lines in the page as seen by the browser in relation to the page I am getting in code.

EDIT. After some testing, I am confident that the user agent header employed by the client is what determines whether or not the class="aspNetHidden" div is served. When I mimic my browser's user agent ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36 Edg/83.0.478.37"), the div is served; if I use some other agent such as "Test Client", the div is not served.

My question then is, is there any documentation on what user agent strings cause the div to be served and which don't? Also, can I prevent this from happening?

Thanks.

答:
This can happen for a number of reasons one of most likely ones is the one that @thangadurai mentioned There may be a script which gets executed onload of the html and changes the html content.. This could be avoided by using a UI testing framework such as Selenium or using headless Chrome programmatically.

One of the other possible reasons is the User-Agent dependant implementation. This can be simply solved by changing the User-Agent header.

EDIT: If you control the webpage you could probably disable ViewState if that's the case. The behavior might be based on detecting the User-Agent capabilities. For your processing, you could go with either string and make it static when you send the request, though it might not be as reliable. Another method to the processing without parsing could be using a regular expression to match specific tags. The specifics of the deciding on rendering ViewState were nicely described by @pfx here.


答:
Change model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])

Change the loss to: loss='binary_crossentropy' because you are doing a binary classification.

As you are doing binary classification you should have only one Dense node at the end, change it to model.add(keras.layers.Dense(1))

Title: tensorflow keras model predicts similar value for every test

Body:
I'm trying to do a binary classification with an RNN with tensorflow. The labels of m y training and test data are 0 and 1. When I try to use my RNN on my finished model, it returns almost the same predictions for every single sample:

model.predict(holdout_x[400:500])

array([[-4.116061 , -1.3410028],
   [-4.1405125, -1.3521721],
   [-4.171639 , -1.3665637],
   [-4.1515126, -1.356805 ],
   [-4.1466017, -1.3546   ],
   [-4.1306634, -1.3479614],
   [-4.1259437, -1.3455958],
   [-4.1161146, -1.3414239],
   [-4.135389 , -1.3504343],
   [-4.1410503, -1.3527975],
   [-4.1413574, -1.3528765],
   [-4.1483955, -1.3562942],
   [-4.208541 , -1.383785 ],
   [-4.212775 , -1.3856986],
   [-4.2415767, -1.3998709],
   [-4.250041 , -1.4033642],
   [-4.2150397, -1.3866954],
   [-4.2094893, -1.3843822],
   [-4.1996937, -1.380172 ],
   [-4.0357003, -1.3077384],
   [-4.030937 , -1.3050178],
   [-4.0273657, -1.3041242],
   [-4.0044518, -1.2939129],
   [-4.003211 , -1.2922926],
   [-4.015193 , -1.2991027],
   [-3.9627366, -1.2757865],
   [-3.9252415, -1.2586563],
   [-3.936089 , -1.265475 ],
   [-3.8994193, -1.2497959],
   [-3.918683 , -1.2593002],
   [-3.7673016, -1.1924615],
   [-3.7568831, -1.1912583]], dtype=float32)

This is how my model looks:

model = tf.keras.Sequential()

model.add(keras.layers.LSTM(200, input_shape=(200, 7), return_sequences=True))

model.add(keras.layers.LSTM(200, input_shape=(200, 7), return_sequences=True))

model.add(keras.layers.LSTM(200))

# Add a Dense layer with 10 units.
model.add(keras.layers.Dense(2))

model.summary()

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

How can I prevent this from happening?


问:
How to extract the Freezing Index from Accelerometer data for FoG detecting?
I'm working on a project to detect Freezing of Gait episodes for Parkinson's Disease patients, and according to this paper and other ones, extracting the freezing index which is "The power in the “freeze” band (3-
8Hz) divided by the power in the locomotor band (0.5-3Hz)" will be a good feature.

Here is the explanation: One standard feature which is extracted from the raw signals is the Freezing Index (FI), defined as the ratio between the power contained in the so-called freezing and locomotion frequency bands (3-8 Hz and 0.5-3 Hz respectively). This feature is convenient since it requires only FFT-computation.

But I cannot how to implement it in Python.

I have a dataframe like this:

Then I did something like this to extract features from the sensors time-series data:

```<code>win_size=200
step_size=40
for col in df.columns:
    if col != 'Label':
        df[col + '_avg'] = df[col].rolling(win_size).mean()[step_size - 1::step_size]
</code>```

Now, I would like to extract the Freezing Index, How can I do this? and I need to someone to explain it to me because I don't fully understand it!

答:
I found this article is very useful. There is a function in this article that computes the average power of the signal in a specific frequency band. And since the Freezing Index is the ratio between the power contained in the so-called freezing and locomotion frequency bands (3-8 Hz and 0.5-3 Hz respectively), we can use this function to get the power in each frequency band and divide them.

Here is the function:

```<code>def bandpower(data, sf, band, window_sec=None, relative=False):
    """Compute the average power of the signal x in a specific frequency band.

    Parameters
    ----------
    data : 1d-array
        Input signal in the time-domain.
    sf : float
        Sampling frequency of the data.
    band : list
        Lower and upper frequencies of the band of interest.
    window_sec : float
        Length of each window in seconds.
        If None, window_sec = (1 / min(band)) * 2
    relative : boolean
        If True, return the relative power (= divided by the total power of the signal).
        If False (default), return the absolute power.

    Return
    ------
    bp : float
        Absolute or relative band power.
    """
    from scipy.signal import welch
    from scipy.integrate import simps
    band = np.asarray(band)
    low, high = band

    # Define window length
    if window_sec is not None:
        nperseg = window_sec * sf
    else:
        nperseg = (2 / low) * sf

    # Compute the modified periodogram (Welch)
    freqs, psd = welch(data, sf, nperseg=nperseg)

    # Frequency resolution
    freq_res = freqs[1] - freqs[0]

    # Find closest indices of band in frequency vector
    idx_band = np.logical_and(freqs >= low, freqs <= high)

    # Integral approximation of the spectrum using Simpson's rule.
    bp = simps(psd[idx_band], dx=freq_res)

    if relative:
        bp /= simps(psd, dx=freq_res)
    return bp
</code>```

Then, I created this simple function to return the FI:

```<code>def freeze_index(data, sf, band1, band2, win_sec=None, relative=False):
    fi = bandpower(data, sf, band1, win_sec, relative) / bandpower(data, sf, band2, win_sec, relative)
    return fi
</code>```

And here is how I called it in the rolling window function:

```<code>for col in df.columns:
    if col != 'Label':
        df[col + '_fi'] = df[col].rolling(win_size).apply(freeze_index, args=(fs, [3, 8], [0.5, 3], win_size,))[step_size - 1::step_size]
</code>```

I hope it's the right solution, and I wish it helps.

Body:
I'm working on a project to detect Freezing of Gait episodes for Parkinson's Disease patients, and according to this paper and other ones, extracting the freezing index which is "The power in the “freeze” band (3-
8Hz) divided by the power in the locomotor band (0.5-3Hz)" will be a good feature.

Here is the explanation: One standard feature which is extracted from the raw signals is the Freezing Index (FI), defined as the ratio between the power contained in the so-called freezing and locomotion frequency bands (3-8 Hz and 0.5-3 Hz respectively). This feature is convenient since it requires only FFT-computation.

But I cannot how to implement it in Python.

I have a dataframe like this:

Then I did something like this to extract features from the sensors time-series data:

win_size=200
step_size=40
for col in df.columns:
    if col != 'Label':
        df[col + '_avg'] = df[col].rolling(win_size).mean()[step_size - 1::step_size]

Now, I would like to extract the Freezing Index, How can I do this? and I need to someone to explain it to me because I don't fully understand it!

Body:
I found this article is very useful. There is a function in this article that computes the average power of the signal in a specific frequency band. And since the Freezing Index is the ratio between the power contained in the so-called freezing and locomotion frequency bands (3-8 Hz and 0.5-3 Hz respectively), we can use this function to get the power in each frequency band and divide them.

Here is the function:

def bandpower(data, sf, band, window_sec=None, relative=False):
    """Compute the average power of the signal x in a specific frequency band.

    Parameters
    ----------
    data : 1d-array
        Input signal in the time-domain.
    sf : float
        Sampling frequency of the data.
    band : list
        Lower and upper frequencies of the band of interest.
    window_sec : float
        Length of each window in seconds.
        If None, window_sec = (1 / min(band)) * 2
    relative : boolean
        If True, return the relative power (= divided by the total power of the signal).
        If False (default), return the absolute power.

    Return
    ------
    bp : float
        Absolute or relative band power.
    """
    from scipy.signal import welch
    from scipy.integrate import simps
    band = np.asarray(band)
    low, high = band

    # Define window length
    if window_sec is not None:
        nperseg = window_sec * sf
    else:
        nperseg = (2 / low) * sf

    # Compute the modified periodogram (Welch)
    freqs, psd = welch(data, sf, nperseg=nperseg)

    # Frequency resolution
    freq_res = freqs[1] - freqs[0]

    # Find closest indices of band in frequency vector
    idx_band = np.logical_and(freqs >= low, freqs <= high)

    # Integral approximation of the spectrum using Simpson's rule.
    bp = simps(psd[idx_band], dx=freq_res)

    if relative:
        bp /= simps(psd, dx=freq_res)
    return bp

Then, I created this simple function to return the FI:

def freeze_index(data, sf, band1, band2, win_sec=None, relative=False):
    fi = bandpower(data, sf, band1, win_sec, relative) / bandpower(data, sf, band2, win_sec, relative)
    return fi

And here is how I called it in the rolling window function:

for col in df.columns:
    if col != 'Label':
        df[col + '_fi'] = df[col].rolling(win_size).apply(freeze_index, args=(fs, [3, 8], [0.5, 3], win_size,))[step_size - 1::step_size]

I hope it's the right solution, and I wish it helps.


问:
Fast method to access random image pixels and at most once
I'm learning OpenCV (C++) and as a simple practice, I designed a simple effect which makes some of image pixels black or white. I want each pixel to be edited at most once; so I added address of all pixels to a vector. But it made my code very slow; specially for large images or high amounts of effect. Here is my code:

void effect1(Mat& img, float amount)    // 100 ≥ amount ≥ 0
{
    vector<uchar*> addresses;
    int channels = img.channels();
    uchar* lastAddress = img.ptr<uchar>(0) + img.total() * channels;
    for (uchar* i = img.ptr<uchar>(0); i < lastAddress; i += channels) addresses.push_back(i);   //Fast Enough
    size_t count = img.total() * amount / 100 / 2;
    for (size_t i = 0; i < count; i++)
    {
        size_t addressIndex = xor128() % addresses.size();   //Fast Enough, xor128() is a fast random number generator
        for (size_t j = 0; j < channels; j++)
        {
            *(addresses[addressIndex] + j) = 255;
        }   //Fast Enough
        addresses.erase(addresses.begin() + addressIndex);    // MAKES CODE EXTREMELY SLOW
    }
    for (size_t i = 0; i < count; i++)
    {
        size_t addressIndex = xor128() % addresses.size();   //Fast Enough, xor128() is a fast random number generator
        for (size_t j = 0; j < channels; j++)
        {
            *(addresses[addressIndex] + j) = 0;
        }   //Fast Enough
        addresses.erase(addresses.begin() + addressIndex);    // MAKES CODE EXTREMELY SLOW
    }
}
```

I think rearranging vector items after erasing an item is what makes my code slow (if I remove addresses.erase, code will run fast).

Is there any fast method to select each random item from a collection (or a number range) at most once?

Also: I'm pretty sure such effect already exists. Does anyone know the name of it?

答:
This answer assumes you have a random bit generator function, since std::random_shuffle requires that. I don't know how xor128 works, so I'll use the functionality of the <random> library.

If we have a population of N items, and we want to select groups of size j and k randomly from that population with no overlap, we can write down the index of each item on a card, shuffle the deck, draw j cards, and then draw k cards. Everything left over is discarded. We can achieve this with the <random> library. Answer pending on how to incorporate a custom PRNG like you implemented with xor128.

This assumes that random_device won't work on your system (many compilers implement it in a way that it will always return the same sequence) so we seed the random generator with current time like the good old fashioned srand our mother used to make.

Untested since I don't know how to use OpenCV. Anyone with a lick of experience with that please edit as appropriate.

```<code>#include <ctime>     // for std::time
#include <numeric>   // for std::iota
#include <random>
#include <vector>

void effect1(Mat& img, float amount, std::mt19937 g)    // 0.0 ≥ amount ≥ 1.00
{
    std::vector<cv::Size> ind(img.total());
    std::iota(ind.begin(), ind.end(), 0);   // fills with 0, 1, 2, ...
    std::random_shuffle(ind.begin(), ind.end(), g);
    cv::Size count = img.total() * amount;

    auto white = get_white<Mat>();  // template function to return this matrix' concept of white
                                    // could easily replace with cv::Vec3d(255,255,255)
                                    // if all your matrices are 3 channel?
    auto black = get_black<Mat>();  // same but... opposite

    auto end = ind.begin() + count;
    for (auto it = ind.begin(), it != end; ++it)
    {
        img.at(*it) = white;
    }
    end = (ind.begin() + 2 * count) > ind.end() ?
               ind.end() :
               ind.begin() + 2 * count;
    for (auto it = ind.begin() + count; it != end; ++it)
    {
        img.at(*it) = black;
    }
}

int main()
{
    std::mt19937 g(std::time(nullptr)); // you normally see this seeded with random_device
                                        // but that's broken on some implementations
                                        // adjust as necessary for your needs
    cv::Mat mat = ... // make your cv objects

    effect1(mat, 0.1, g);

    // display it here

}
</code>```

Another approach

Instead of shuffling indices and drawing cards from a deck, assume each pixel has a random probability of switching to white, switching to black, or staying the same. If your amount is 0.4, then select a random number between 0.0 and 1.0, any result between 0.0 and 0.4 flips the pixel black, and betwen 0.4 and 0.8 flips it white, otherwise it stays the same.

General algorithm:

```<code>given probability of flipping -> f
for each pixel in image -> p:
    get next random float([0.0, 1.0)) -> r
    if r < f
        then p <- BLACK
    else if r < 2*f
        then p <- WHITE
</code>```

You won't get the same number of white/black pixels each time, but that's randomness! We're generating a random number for each pixel anyway for the shuffling algorithm. This has the same complexity unless I'm mistaken.

Body:
I'm learning OpenCV (C++) and as a simple practice, I designed a simple effect which makes some of image pixels black or white. I want each pixel to be edited at most once; so I added address of all pixels to a vector. But it made my code very slow; specially for large images or high amounts of effect. Here is my code:

void effect1(Mat& img, float amount)    // 100 ≥ amount ≥ 0
{
    vector<uchar*> addresses;
    int channels = img.channels();
    uchar* lastAddress = img.ptr<uchar>(0) + img.total() * channels;
    for (uchar* i = img.ptr<uchar>(0); i < lastAddress; i += channels) addresses.push_back(i);   //Fast Enough
    size_t count = img.total() * amount / 100 / 2;
    for (size_t i = 0; i < count; i++)
    {
        size_t addressIndex = xor128() % addresses.size();   //Fast Enough, xor128() is a fast random number generator
        for (size_t j = 0; j < channels; j++)
        {
            *(addresses[addressIndex] + j) = 255;
        }   //Fast Enough
        addresses.erase(addresses.begin() + addressIndex);    // MAKES CODE EXTREMELY SLOW
    }
    for (size_t i = 0; i < count; i++)
    {
        size_t addressIndex = xor128() % addresses.size();   //Fast Enough, xor128() is a fast random number generator
        for (size_t j = 0; j < channels; j++)
        {
            *(addresses[addressIndex] + j) = 0;
        }   //Fast Enough
        addresses.erase(addresses.begin() + addressIndex);    // MAKES CODE EXTREMELY SLOW
    }
}

I think rearranging vector items after erasing an item is what makes my code slow (if I remove addresses.erase, code will run fast).

Is there any fast method to select each random item from a collection (or a number range) at most once?

Also: I'm pretty sure such effect already exists. Does anyone know the name of it?

Body:
This answer assumes you have a random bit generator function, since std::random_shuffle requires that. I don't know how xor128 works, so I'll use the functionality of the <random> library.

If we have a population of N items, and we want to select groups of size j and k randomly from that population with no overlap, we can write down the index of each item on a card, shuffle the deck, draw j cards, and then draw k cards. Everything left over is discarded. We can achieve this with the <random> library. Answer pending on how to incorporate a custom PRNG like you implemented with xor128.

This assumes that random_device won't work on your system (many compilers implement it in a way that it will always return the same sequence) so we seed the random generator with current time like the good old fashioned srand our mother used to make.

Untested since I don't know how to use OpenCV. Anyone with a lick of experience with that please edit as appropriate.

#include <ctime>     // for std::time
#include <numeric>   // for std::iota
#include <random>
#include <vector>

void effect1(Mat& img, float amount, std::mt19937 g)    // 0.0 ≥ amount ≥ 1.00
{
    std::vector<cv::Size> ind(img.total());
    std::iota(ind.begin(), ind.end(), 0);   // fills with 0, 1, 2, ...
    std::random_shuffle(ind.begin(), ind.end(), g);
    cv::Size count = img.total() * amount;

    auto white = get_white<Mat>();  // template function to return this matrix' concept of white
                                    // could easily replace with cv::Vec3d(255,255,255)
                                    // if all your matrices are 3 channel?
    auto black = get_black<Mat>();  // same but... opposite

    auto end = ind.begin() + count;
    for (auto it = ind.begin(), it != end; ++it)
    {
        img.at(*it) = white;
    }
    end = (ind.begin() + 2 * count) > ind.end() ?
               ind.end() :
               ind.begin() + 2 * count;
    for (auto it = ind.begin() + count; it != end; ++it)
    {
        img.at(*it) = black;
    }
}

int main()
{
    std::mt19937 g(std::time(nullptr)); // you normally see this seeded with random_device
                                        // but that's broken on some implementations
                                        // adjust as necessary for your needs
    cv::Mat mat = ... // make your cv objects

    effect1(mat, 0.1, g);

    // display it here

}

Another approach

Instead of shuffling indices and drawing cards from a deck, assume each pixel has a random probability of switching to white, switching to black, or staying the same. If your amount is 0.4, then select a random number between 0.0 and 1.0, any result between 0.0 and 0.4 flips the pixel black, and betwen 0.4 and 0.8 flips it white, otherwise it stays the same.

General algorithm:

given probability of flipping -> f
for each pixel in image -> p:
    get next random float([0.0, 1.0)) -> r
    if r < f
        then p <- BLACK
    else if r < 2*f
        then p <- WHITE

You won't get the same number of white/black pixels each time, but that's randomness! We're generating a random number for each pixel anyway for the shuffling algorithm. This has the same complexity unless I'm mistaken.


问:
Vlookup() equivalent in Dplyr
My df looks like:

```<code>library(tidyverse)
df_1 <- tibble::tribble(
          ~sub_date, ~value_1, ~value_2,
          "2020-05",       58,      130,
          "2020-05",       58,       "check",
          "2020-03",       50,      120,
          "2020-03",       55,       "check",
          "2020-03",       55,       "check"
          )
</code>```

I want to change the values of the rows containing "check" with the reference values here:

```<code>df_ref <- tibble::tribble(
            ~sub_date, ~ref_value,
            "2020-05",        123,
            "2020-03",        234
            )
</code>```

Basically - using the df_ref table as a reference only for the rows containing check.

I want to use the equivalent of a lookup() in excel, used in a if() function.

Final result being:

```<code>df_final <- tibble::tribble(
              ~sub_date, ~value_1, ~value_2,
              "2020-05",       58,      130,
              "2020-05",       58,      123,
              "2020-03",       50,      120,
              "2020-03",       55,      234,
              "2020-03",       55,      234
              )
</code>```

答:
Good luck when there are multiple matches</p>

```<code>library(tidyverse)
df_1 <- tibble::tribble(
  ~sub_date, ~value_1, ~value_2,
  "2020-05",       58,      "130",
  "2020-05",       58,       "check",
  "2020-03",       50,      "120",
  "2020-03",       55,       "check",
  "2020-03",       55,       "check"
)

df_ref <- tibble::tribble(
  ~sub_date, ~ref_value,
  "2020-05",        123,
  "2020-03",        234
)

df_1 %>%
  left_join(df_ref) %>%
  mutate(value_2_true = ifelse(value_2 == "check",ref_value,value_2)) %>%
  mutate(value_2 = value_2_true %>% as.numeric()) %>%
  select(-value_2_true,-ref_value)
</code>```

Title: Vlookup() equivalent in Dplyr

Body:
My df looks like:

library(tidyverse)
df_1 <- tibble::tribble(
          ~sub_date, ~value_1, ~value_2,
          "2020-05",       58,      130,
          "2020-05",       58,       "check",
          "2020-03",       50,      120,
          "2020-03",       55,       "check",
          "2020-03",       55,       "check"
          )

I want to change the values of the rows containing "check" with the reference values here:

df_ref <- tibble::tribble(
            ~sub_date, ~ref_value,
            "2020-05",        123,
            "2020-03",        234
            )

Basically - using the df_ref table as a reference only for the rows containing check.

I want to use the equivalent of a lookup() in excel, used in a if() function.

Final result being:

df_final <- tibble::tribble(
              ~sub_date, ~value_1, ~value_2,
              "2020-05",       58,      130,
              "2020-05",       58,      123,
              "2020-03",       50,      120,
              "2020-03",       55,      234,
              "2020-03",       55,      234
              )

Body:
Good luck when there are multiple matches

library(tidyverse)
df_1 <- tibble::tribble(
  ~sub_date, ~value_1, ~value_2,
  "2020-05",       58,      "130",
  "2020-05",       58,       "check",
  "2020-03",       50,      "120",
  "2020-03",       55,       "check",
  "2020-03",       55,       "check"
)

df_ref <- tibble::tribble(
  ~sub_date, ~ref_value,
  "2020-05",        123,
  "2020-03",        234
)

df_1 %>%
  left_join(df_ref) %>%
  mutate(value_2_true = ifelse(value_2 == "check",ref_value,value_2)) %>%
  mutate(value_2 = value_2_true %>% as.numeric()) %>%
  select(-value_2_true,-ref_value)


问:
MongoDB error: couldn't connect to server 127.0.0.1:27017
When running "mongo" (even as sudo) on macOS I'm getting the following error:

➜  server git:(master) ✗ mongo
MongoDB shell version v4.0.4
connecting to: mongodb://127.0.0.1:27017
2018-12-17T17:14:54.659-0800 E QUERY    [js] Error: couldn't connect to server 127.0.0.1:27017, connection attempt failed: SocketException: Error connecting to 127.0.0.1:27017 :: caused by :: Connection refused :
connect@src/mongo/shell/mongo.js:257:13
@(connect):1:6
exception: connect failed```
</div>
</div>
</p>

<p><strong>However when I run "mongod" everything seems to be running smoothely besides a few warning messages:</strong></p>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>➜  server git:(master) ✗ sudo mongod
2018-12-17T17:25:51.718-0800 I CONTROL  [main] Automatically disabling TLS 1.0, to force-enable TLS 1.0 specify --sslDisabledProtocols 'none'
2018-12-17T17:25:51.732-0800 I CONTROL  [initandlisten] MongoDB starting : pid=5919 port=27017 dbpath=/data/db 64-bit host=Aarons-MacBook-Air-3.local
2018-12-17T17:25:51.732-0800 I CONTROL  [initandlisten] db version v4.0.4
2018-12-17T17:25:51.732-0800 I CONTROL  [initandlisten] git version: f288a3bdf201007f3693c58e140056adf8b04839
2018-12-17T17:25:51.732-0800 I CONTROL  [initandlisten] allocator: system
2018-12-17T17:25:51.732-0800 I CONTROL  [initandlisten] modules: none
2018-12-17T17:25:51.732-0800 I CONTROL  [initandlisten] build environment:
2018-12-17T17:25:51.732-0800 I CONTROL  [initandlisten]     distarch: x86_64
2018-12-17T17:25:51.732-0800 I CONTROL  [initandlisten]     target_arch: x86_64
2018-12-17T17:25:51.732-0800 I CONTROL  [initandlisten] options: {}
2018-12-17T17:25:51.733-0800 I STORAGE  [initandlisten] Detected data files in /data/db created by the 'wiredTiger' storage engine, so setting the active storage engine to 'wiredTiger'.
2018-12-17T17:25:51.733-0800 I STORAGE  [initandlisten] wiredtiger_open config: create,cache_size=3584M,session_max=20000,eviction=(threads_min=4,threads_max=4),config_base=false,statistics=(fast),log=(enabled=true,archive=true,path=journal,compressor=snappy),file_manager=(close_idle_time=100000),statistics_log=(wait=0),verbose=(recovery_progress),
2018-12-17T17:25:52.678-0800 I STORAGE  [initandlisten] WiredTiger message [1545096352:678713][5919:0x10bfe35c0], txn-recover: Main recovery loop: starting at 8/6528 to 9/256
2018-12-17T17:25:52.846-0800 I STORAGE  [initandlisten] WiredTiger message [1545096352:846951][5919:0x10bfe35c0], txn-recover: Recovering log 8 through 9
2018-12-17T17:25:52.961-0800 I STORAGE  [initandlisten] WiredTiger message [1545096352:961090][5919:0x10bfe35c0], txn-recover: Recovering log 9 through 9
2018-12-17T17:25:53.044-0800 I STORAGE  [initandlisten] WiredTiger message [1545096353:44078][5919:0x10bfe35c0], txn-recover: Set global recovery timestamp: 0
2018-12-17T17:25:53.174-0800 I RECOVERY [initandlisten] WiredTiger recoveryTimestamp. Ts: Timestamp(0, 0)
2018-12-17T17:25:53.295-0800 I CONTROL  [initandlisten]
2018-12-17T17:25:53.295-0800 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2018-12-17T17:25:53.295-0800 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2018-12-17T17:25:53.295-0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2018-12-17T17:25:53.295-0800 I CONTROL  [initandlisten]
2018-12-17T17:25:53.295-0800 I CONTROL  [initandlisten] ** WARNING: This server is bound to localhost.
2018-12-17T17:25:53.295-0800 I CONTROL  [initandlisten] **          Remote systems will be unable to connect to this server.
2018-12-17T17:25:53.296-0800 I CONTROL  [initandlisten] **          Start the server with --bind_ip <address> to specify which IP
2018-12-17T17:25:53.296-0800 I CONTROL  [initandlisten] **          addresses it should serve responses from, or with --bind_ip_all to
2018-12-17T17:25:53.296-0800 I CONTROL  [initandlisten] **          bind to all interfaces. If this behavior is desired, start the
2018-12-17T17:25:53.296-0800 I CONTROL  [initandlisten] **          server with --bind_ip 127.0.0.1 to disable this warning.
2018-12-17T17:25:53.296-0800 I CONTROL  [initandlisten]
2018-12-17T17:25:53.296-0800 I CONTROL  [initandlisten]
2018-12-17T17:25:53.296-0800 I CONTROL  [initandlisten] ** WARNING: soft rlimits too low. Number of files is 256, should be at least 1000
2018-12-17T17:25:53.396-0800 I FTDC     [initandlisten] Initializing full-time diagnostic data capture with directory '/data/db/diagnostic.data'
2018-12-17T17:25:53.403-0800 I NETWORK  [initandlisten] waiting for connections on port 27017</code>```

I thought it was incorrectly installed at first, but even after downloading the tar file, adding the bin file directory to my path variable, and creating the /data/db path to which mongod points to I am still seeing this error.
The good news is that I can read/write on this database through the mongo console, but my goal is to be able to run it with node. I see a similar error when attempting to run my node project:

➜  server git:(master) ✗ node index.js
(node:6064) UnhandledPromiseRejectionWarning: MongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017]
    at Pool.<anonymous> (/Users/aaronmednick/code/aaronjospehm/mern_app/server/node_modules/mongodb-core/lib/topologies/server.js:564:11)
    at Pool.emit (events.js:182:13)
    at Connection.<anonymous> (/Users/aaronmednick/code/aaronjospehm/mern_app/server/node_modules/mongodb-core/lib/connection/pool.js:317:12)
    at Object.onceWrapper (events.js:273:13)
    at Connection.emit (events.js:182:13)
    at Socket.<anonymous> (/Users/aaronmednick/code/aaronjospehm/mern_app/server/node_modules/mongodb-core/lib/connection/connection.js:246:50)
    at Object.onceWrapper (events.js:273:13)
    at Socket.emit (events.js:182:13)
    at emitErrorNT (internal/streams/destroy.js:82:8)
    at emitErrorAndCloseNT (internal/streams/destroy.js:50:3)
    at process.internalTickCallback (internal/process/next_tick.js:72:19)
(node:6064) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:6064) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.```
</div>
</div>
</p>

<p><strong>Here's my code for reference:</strong></p>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>const { GraphQLServer } = require('graphql-yoga');

const mongoose = require("mongoose");

mongoose.connect("mongodb://localhost/test5", { useNewUrlParser: true } );

const Todo = mongoose.model('Todo', {
 text: String,
 complete: Boolean
});

const typeDefs = `
  type Query {
    hello(name: String): String!
  }
  type Todo {
   id: ID!
   text: String!
   complete: Boolean!
  }
  type Mutation {
   createTodo(test: String!): Todo
  }
`

const resolvers = {
  Query: {
    hello: (_, { name }) => `Hello ${name || 'World'}`,
  },
  Mutation: {
   createTodo: async (_, { text }) => {
    const todo = new Todo({ text, complete: false});
    await todo.save();
    return todo;
   }
  }
}

const server = new GraphQLServer({ typeDefs, resolvers })

mongoose.connection.once('open', function() {
 server.start(() => console.log('Server is running on localhost:4000'));
});

module.exports = mongoose;</code>```

Any ideas?

答:
What I suggest you to do is to check /var/log/mongodb.
In my case I've got messages like these:

Failed to unlink socket file /tmp/mongodb-27017.sock Operation not
  permitted Fatal Assertion 40486 at
  src/mongo/transport/transport_layer_asio.cpp 68

So I've tried to remove the sock and restarted the mongod service which failed to start. I'm not sure why it happens but it has fixed the problem

```<code>sudo rm -rf /tmp/mongodb-27017.sock
sudo service mongod start
</code>```

Body:
When running "mongo" (even as sudo) on macOS I'm getting the following error:

➜  server git:(master) ✗ mongo
MongoDB shell version v4.0.4
connecting to: mongodb://127.0.0.1:27017
2018-12-17T17:14:54.659-0800 E QUERY    [js] Error: couldn't connect to server 127.0.0.1:27017, connection attempt failed: SocketException: Error connecting to 127.0.0.1:27017 :: caused by :: Connection refused :
connect@src/mongo/shell/mongo.js:257:13
@(connect):1:6
exception: connect failed

However when I run "mongod" everything seems to be running smoothely besides a few warning messages:

➜  server git:(master) ✗ sudo mongod
2018-12-17T17:25:51.718-0800 I CONTROL  [main] Automatically disabling TLS 1.0, to force-enable TLS 1.0 specify --sslDisabledProtocols 'none'
2018-12-17T17:25:51.732-0800 I CONTROL  [initandlisten] MongoDB starting : pid=5919 port=27017 dbpath=/data/db 64-bit host=Aarons-MacBook-Air-3.local
2018-12-17T17:25:51.732-0800 I CONTROL  [initandlisten] db version v4.0.4
2018-12-17T17:25:51.732-0800 I CONTROL  [initandlisten] git version: f288a3bdf201007f3693c58e140056adf8b04839
2018-12-17T17:25:51.732-0800 I CONTROL  [initandlisten] allocator: system
2018-12-17T17:25:51.732-0800 I CONTROL  [initandlisten] modules: none
2018-12-17T17:25:51.732-0800 I CONTROL  [initandlisten] build environment:
2018-12-17T17:25:51.732-0800 I CONTROL  [initandlisten]     distarch: x86_64
2018-12-17T17:25:51.732-0800 I CONTROL  [initandlisten]     target_arch: x86_64
2018-12-17T17:25:51.732-0800 I CONTROL  [initandlisten] options: {}
2018-12-17T17:25:51.733-0800 I STORAGE  [initandlisten] Detected data files in /data/db created by the 'wiredTiger' storage engine, so setting the active storage engine to 'wiredTiger'.
2018-12-17T17:25:51.733-0800 I STORAGE  [initandlisten] wiredtiger_open config: create,cache_size=3584M,session_max=20000,eviction=(threads_min=4,threads_max=4),config_base=false,statistics=(fast),log=(enabled=true,archive=true,path=journal,compressor=snappy),file_manager=(close_idle_time=100000),statistics_log=(wait=0),verbose=(recovery_progress),
2018-12-17T17:25:52.678-0800 I STORAGE  [initandlisten] WiredTiger message [1545096352:678713][5919:0x10bfe35c0], txn-recover: Main recovery loop: starting at 8/6528 to 9/256
2018-12-17T17:25:52.846-0800 I STORAGE  [initandlisten] WiredTiger message [1545096352:846951][5919:0x10bfe35c0], txn-recover: Recovering log 8 through 9
2018-12-17T17:25:52.961-0800 I STORAGE  [initandlisten] WiredTiger message [1545096352:961090][5919:0x10bfe35c0], txn-recover: Recovering log 9 through 9
2018-12-17T17:25:53.044-0800 I STORAGE  [initandlisten] WiredTiger message [1545096353:44078][5919:0x10bfe35c0], txn-recover: Set global recovery timestamp: 0
2018-12-17T17:25:53.174-0800 I RECOVERY [initandlisten] WiredTiger recoveryTimestamp. Ts: Timestamp(0, 0)
2018-12-17T17:25:53.295-0800 I CONTROL  [initandlisten]
2018-12-17T17:25:53.295-0800 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2018-12-17T17:25:53.295-0800 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2018-12-17T17:25:53.295-0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2018-12-17T17:25:53.295-0800 I CONTROL  [initandlisten]
2018-12-17T17:25:53.295-0800 I CONTROL  [initandlisten] ** WARNING: This server is bound to localhost.
2018-12-17T17:25:53.295-0800 I CONTROL  [initandlisten] **          Remote systems will be unable to connect to this server.
2018-12-17T17:25:53.296-0800 I CONTROL  [initandlisten] **          Start the server with --bind_ip <address> to specify which IP
2018-12-17T17:25:53.296-0800 I CONTROL  [initandlisten] **          addresses it should serve responses from, or with --bind_ip_all to
2018-12-17T17:25:53.296-0800 I CONTROL  [initandlisten] **          bind to all interfaces. If this behavior is desired, start the
2018-12-17T17:25:53.296-0800 I CONTROL  [initandlisten] **          server with --bind_ip 127.0.0.1 to disable this warning.
2018-12-17T17:25:53.296-0800 I CONTROL  [initandlisten]
2018-12-17T17:25:53.296-0800 I CONTROL  [initandlisten]
2018-12-17T17:25:53.296-0800 I CONTROL  [initandlisten] ** WARNING: soft rlimits too low. Number of files is 256, should be at least 1000
2018-12-17T17:25:53.396-0800 I FTDC     [initandlisten] Initializing full-time diagnostic data capture with directory '/data/db/diagnostic.data'
2018-12-17T17:25:53.403-0800 I NETWORK  [initandlisten] waiting for connections on port 27017

I thought it was incorrectly installed at first, but even after downloading the tar file, adding the bin file directory to my path variable, and creating the /data/db path to which mongod points to I am still seeing this error.
The good news is that I can read/write on this database through the mongo console, but my goal is to be able to run it with node. I see a similar error when attempting to run my node project:

➜  server git:(master) ✗ node index.js
(node:6064) UnhandledPromiseRejectionWarning: MongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017]
    at Pool.<anonymous> (/Users/aaronmednick/code/aaronjospehm/mern_app/server/node_modules/mongodb-core/lib/topologies/server.js:564:11)
    at Pool.emit (events.js:182:13)
    at Connection.<anonymous> (/Users/aaronmednick/code/aaronjospehm/mern_app/server/node_modules/mongodb-core/lib/connection/pool.js:317:12)
    at Object.onceWrapper (events.js:273:13)
    at Connection.emit (events.js:182:13)
    at Socket.<anonymous> (/Users/aaronmednick/code/aaronjospehm/mern_app/server/node_modules/mongodb-core/lib/connection/connection.js:246:50)
    at Object.onceWrapper (events.js:273:13)
    at Socket.emit (events.js:182:13)
    at emitErrorNT (internal/streams/destroy.js:82:8)
    at emitErrorAndCloseNT (internal/streams/destroy.js:50:3)
    at process.internalTickCallback (internal/process/next_tick.js:72:19)
(node:6064) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:6064) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Here's my code for reference:

const { GraphQLServer } = require('graphql-yoga');

const mongoose = require("mongoose");

mongoose.connect("mongodb://localhost/test5", { useNewUrlParser: true } );

const Todo = mongoose.model('Todo', {
 text: String,
 complete: Boolean
});

const typeDefs = `
  type Query {
    hello(name: String): String!
  }
  type Todo {
   id: ID!
   text: String!
   complete: Boolean!
  }
  type Mutation {
   createTodo(test: String!): Todo
  }
`

const resolvers = {
  Query: {
    hello: (_, { name }) => `Hello ${name || 'World'}`,
  },
  Mutation: {
   createTodo: async (_, { text }) => {
    const todo = new Todo({ text, complete: false});
    await todo.save();
    return todo;
   }
  }
}

const server = new GraphQLServer({ typeDefs, resolvers })

mongoose.connection.once('open', function() {
 server.start(() => console.log('Server is running on localhost:4000'));
});

module.exports = mongoose;

Any ideas?

Body:
What I suggest you to do is to check /var/log/mongodb.
In my case I've got messages like these:

Failed to unlink socket file /tmp/mongodb-27017.sock Operation not
  permitted Fatal Assertion 40486 at
  src/mongo/transport/transport_layer_asio.cpp 68

So I've tried to remove the sock and restarted the mongod service which failed to start. I'm not sure why it happens but it has fixed the problem

sudo rm -rf /tmp/mongodb-27017.sock
sudo service mongod start


问:
Change recyclerview adapter items from own activity after clicking on button inside adapter
I built a simple quiz app with sqlite database
There is some quiz headers and into this quiz headers we have some questions that show by recycler view. All questions have one question title and 4 answers and one correct answer. user chooses the radio button answers and after that click on confirm button that is located as item at the bottom of recycler view.
I can catch the correct answer with a simple way and send it to the activity with an interface. But i want to show the correct and wrong answers with changing the radio buttons color but I can't create another method and change the view holder items because I can't access to the view holders outside of 'onBindViewHolder' method . I can handle this with another adapter . I mean I can create a fake adapter that just show answers . Is it a right way ?

This is my code. It's a little messy. Sorry about that

```<code>public class QuestionRecyclerAdapter extends RecyclerView.Adapter<QuestionRecyclerAdapter.ViewHolder> {

private Context context;
private List<QuestionHolder> questionHolders;
private OnQuestionAnswerSelect onQuestionAnswerSelect;
private OnConfirmButtonClicked onConfirmButtonClicked;

public QuestionRecyclerAdapter(Context context, List<QuestionHolder> questionHolders) {
    this.context = context;
    this.questionHolders = questionHolders;
}

public void setOnQuestionAnswerSelect(OnQuestionAnswerSelect onQuestionAnswerSelect) {
    this.onQuestionAnswerSelect = onQuestionAnswerSelect;
}
public void setOnConfirmButtonClicked(OnConfirmButtonClicked onConfirmButtonClicked){
    this.onConfirmButtonClicked = onConfirmButtonClicked;
}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

    View itemView;

    if (viewType == R.layout.question_item)
        itemView = LayoutInflater.from(context).inflate(R.layout.question_item, parent, false);
    else
        itemView = LayoutInflater.from(context).inflate(R.layout.question_recycler_confirm_button, parent, false);

    return new ViewHolder(itemView);
}

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {

    if (position != questionHolders.size()) {
        QuestionModel currentModel = questionHolders.get(position).getQuestionModel();
        holder.txtQuestion.setText(currentModel.getTitle());

        holder.rBtnAnswer1.setText(currentModel.getOption1());
        holder.rBtnAnswer2.setText(currentModel.getOption2());
        holder.rBtnAnswer3.setText(currentModel.getOption3());
        holder.rBtnAnswer4.setText(currentModel.getOption4());

        if (onQuestionAnswerSelect != null) {

            holder.questionRadioGroup.setOnCheckedChangeListener((v, i) -> {
                RadioButton rBtnSelected = holder.questionRadioGroup.findViewById(holder.questionRadioGroup.getCheckedRadioButtonId());
                int selectedRadioIndex = holder.questionRadioGroup.indexOfChild(rBtnSelected) + 1;

                if (selectedRadioIndex == questionHolders.get(position).getQuestionModel().getCorrectNumber()) {
                    onQuestionAnswerSelect.onAnswerSelected(questionHolders.get(position).get_id(), true);
                } else {
                    onQuestionAnswerSelect.onAnswerSelected(questionHolders.get(position).get_id(), false);
                }
            });
        }
    }else {
        holder.btnConfirm.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (onConfirmButtonClicked != null)
                    onConfirmButtonClicked.onConfirmClicked();
            }
        });
    }
}

@Override
public int getItemCount() {
    return questionHolders.size() + 1;
}

@Override
public int getItemViewType(int position) {
    return (position == questionHolders.size()) ? R.layout.question_recycler_confirm_button : R.layout.question_item;
}

public class ViewHolder extends RecyclerView.ViewHolder {

    public TextView txtQuestion;
    public RadioGroup questionRadioGroup;
    public RadioButton rBtnAnswer1;
    public RadioButton rBtnAnswer2;
    public RadioButton rBtnAnswer3;
    public RadioButton rBtnAnswer4;
    public Button btnConfirm;

    public ViewHolder(@NonNull View itemView) {
        super(itemView);

        txtQuestion = itemView.findViewById(R.id.txtQuestion);
        questionRadioGroup = itemView.findViewById(R.id.questionRadioGroup);
        rBtnAnswer1 = itemView.findViewById(R.id.rBtnAnswer1);
        rBtnAnswer2 = itemView.findViewById(R.id.rBtnAnswer2);
        rBtnAnswer3 = itemView.findViewById(R.id.rBtnAnswer3);
        rBtnAnswer4 = itemView.findViewById(R.id.rBtnAnswer4);
        btnConfirm = itemView.findViewById(R.id.btnConfirm);
    }
}
</code>```

}

```<code>public class QuizActivity extends AppCompatActivity {

RecyclerView questionRecyclerView ;
QuestionRecyclerAdapter adapter ;
QuestionDatabaseHelper questionDatabaseHelper ;
Map<Integer,Boolean> answeredRecords = new HashMap<>();

int score ;

@Override
protected void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_quiz);

    questionRecyclerView = findViewById(R.id.questionRecyclerView);
    questionDatabaseHelper = new QuestionDatabaseHelper(this);

    int selectedId = getIntent().getIntExtra(Constants.SELECTED_ID,0);
    score = 0 ;

    List<QuestionHolder> questionHolders = questionDatabaseHelper.getAllQuestionHoldersById(selectedId);
    adapter = new QuestionRecyclerAdapter(this,questionHolders);
    questionRecyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));
    questionRecyclerView.setAdapter(adapter);

    adapter.setOnQuestionAnswerSelect(new OnQuestionAnswerSelect() {
        @Override
        public void onAnswerSelected(int questionNumber, boolean isCorrect) {
            answeredRecords.put(questionNumber,isCorrect);
        }
    });
    adapter.setOnConfirmButtonClicked(new OnConfirmButtonClicked() {
        @Override
        public void onConfirmClicked() {
            score = 0 ;
            for(Map.Entry<Integer,Boolean> item : answeredRecords.entrySet()){
                if (item.getValue())
                    score++;
            }
            Log.e("THE SCORE IS ", String.valueOf(score));
        }
    });
}
private void displayRecords(){

    for(Map.Entry<Integer,Boolean> item : answeredRecords.entrySet()){
        Log.e("AAA",item.getKey() + " : " + item.getValue());
    }
}
</code>```

}

答:
Make a function in adapter and send holder to activity by calling that function.
first make viewholder named holder1.

```<code>ViewHolder holder1;
</code>```

then at the onBindViewHolder method add this:

```<code>holder1 = holder;

public ViewHolder getHolder(){
    return holder1;
}
</code>```

now you can use it in your Activity like this:

```<code>adapter.getHolder.rBtnAnswer1.setBackgroundColor(Color.parseColor("#FFFFFF")); //this is a example.
</code>```

Body:
I built a simple quiz app with sqlite database
There is some quiz headers and into this quiz headers we have some questions that show by recycler view. All questions have one question title and 4 answers and one correct answer. user chooses the radio button answers and after that click on confirm button that is located as item at the bottom of recycler view.
I can catch the correct answer with a simple way and send it to the activity with an interface. But i want to show the correct and wrong answers with changing the radio buttons color but I can't create another method and change the view holder items because I can't access to the view holders outside of 'onBindViewHolder' method . I can handle this with another adapter . I mean I can create a fake adapter that just show answers . Is it a right way ?

This is my code. It's a little messy. Sorry about that

public class QuestionRecyclerAdapter extends RecyclerView.Adapter<QuestionRecyclerAdapter.ViewHolder> {

private Context context;
private List<QuestionHolder> questionHolders;
private OnQuestionAnswerSelect onQuestionAnswerSelect;
private OnConfirmButtonClicked onConfirmButtonClicked;

public QuestionRecyclerAdapter(Context context, List<QuestionHolder> questionHolders) {
    this.context = context;
    this.questionHolders = questionHolders;
}

public void setOnQuestionAnswerSelect(OnQuestionAnswerSelect onQuestionAnswerSelect) {
    this.onQuestionAnswerSelect = onQuestionAnswerSelect;
}
public void setOnConfirmButtonClicked(OnConfirmButtonClicked onConfirmButtonClicked){
    this.onConfirmButtonClicked = onConfirmButtonClicked;
}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

    View itemView;

    if (viewType == R.layout.question_item)
        itemView = LayoutInflater.from(context).inflate(R.layout.question_item, parent, false);
    else
        itemView = LayoutInflater.from(context).inflate(R.layout.question_recycler_confirm_button, parent, false);

    return new ViewHolder(itemView);
}

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {

    if (position != questionHolders.size()) {
        QuestionModel currentModel = questionHolders.get(position).getQuestionModel();
        holder.txtQuestion.setText(currentModel.getTitle());

        holder.rBtnAnswer1.setText(currentModel.getOption1());
        holder.rBtnAnswer2.setText(currentModel.getOption2());
        holder.rBtnAnswer3.setText(currentModel.getOption3());
        holder.rBtnAnswer4.setText(currentModel.getOption4());

        if (onQuestionAnswerSelect != null) {

            holder.questionRadioGroup.setOnCheckedChangeListener((v, i) -> {
                RadioButton rBtnSelected = holder.questionRadioGroup.findViewById(holder.questionRadioGroup.getCheckedRadioButtonId());
                int selectedRadioIndex = holder.questionRadioGroup.indexOfChild(rBtnSelected) + 1;

                if (selectedRadioIndex == questionHolders.get(position).getQuestionModel().getCorrectNumber()) {
                    onQuestionAnswerSelect.onAnswerSelected(questionHolders.get(position).get_id(), true);
                } else {
                    onQuestionAnswerSelect.onAnswerSelected(questionHolders.get(position).get_id(), false);
                }
            });
        }
    }else {
        holder.btnConfirm.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (onConfirmButtonClicked != null)
                    onConfirmButtonClicked.onConfirmClicked();
            }
        });
    }
}

@Override
public int getItemCount() {
    return questionHolders.size() + 1;
}

@Override
public int getItemViewType(int position) {
    return (position == questionHolders.size()) ? R.layout.question_recycler_confirm_button : R.layout.question_item;
}

public class ViewHolder extends RecyclerView.ViewHolder {

    public TextView txtQuestion;
    public RadioGroup questionRadioGroup;
    public RadioButton rBtnAnswer1;
    public RadioButton rBtnAnswer2;
    public RadioButton rBtnAnswer3;
    public RadioButton rBtnAnswer4;
    public Button btnConfirm;

    public ViewHolder(@NonNull View itemView) {
        super(itemView);

        txtQuestion = itemView.findViewById(R.id.txtQuestion);
        questionRadioGroup = itemView.findViewById(R.id.questionRadioGroup);
        rBtnAnswer1 = itemView.findViewById(R.id.rBtnAnswer1);
        rBtnAnswer2 = itemView.findViewById(R.id.rBtnAnswer2);
        rBtnAnswer3 = itemView.findViewById(R.id.rBtnAnswer3);
        rBtnAnswer4 = itemView.findViewById(R.id.rBtnAnswer4);
        btnConfirm = itemView.findViewById(R.id.btnConfirm);
    }
}

}

public class QuizActivity extends AppCompatActivity {

RecyclerView questionRecyclerView ;
QuestionRecyclerAdapter adapter ;
QuestionDatabaseHelper questionDatabaseHelper ;
Map<Integer,Boolean> answeredRecords = new HashMap<>();

int score ;

@Override
protected void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_quiz);

    questionRecyclerView = findViewById(R.id.questionRecyclerView);
    questionDatabaseHelper = new QuestionDatabaseHelper(this);

    int selectedId = getIntent().getIntExtra(Constants.SELECTED_ID,0);
    score = 0 ;

    List<QuestionHolder> questionHolders = questionDatabaseHelper.getAllQuestionHoldersById(selectedId);
    adapter = new QuestionRecyclerAdapter(this,questionHolders);
    questionRecyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));
    questionRecyclerView.setAdapter(adapter);

    adapter.setOnQuestionAnswerSelect(new OnQuestionAnswerSelect() {
        @Override
        public void onAnswerSelected(int questionNumber, boolean isCorrect) {
            answeredRecords.put(questionNumber,isCorrect);
        }
    });
    adapter.setOnConfirmButtonClicked(new OnConfirmButtonClicked() {
        @Override
        public void onConfirmClicked() {
            score = 0 ;
            for(Map.Entry<Integer,Boolean> item : answeredRecords.entrySet()){
                if (item.getValue())
                    score++;
            }
            Log.e("THE SCORE IS ", String.valueOf(score));
        }
    });
}
private void displayRecords(){

    for(Map.Entry<Integer,Boolean> item : answeredRecords.entrySet()){
        Log.e("AAA",item.getKey() + " : " + item.getValue());
    }
}

}

Body:
Make a function in adapter and send holder to activity by calling that function.
first make viewholder named holder1.

ViewHolder holder1;

then at the onBindViewHolder method add this:

holder1 = holder;

public ViewHolder getHolder(){
    return holder1;
}

now you can use it in your Activity like this:

adapter.getHolder.rBtnAnswer1.setBackgroundColor(Color.parseColor("#FFFFFF")); //this is a example.


问:
Convert integer value to fractional value (decimal)
Looking for a way to convert a positive number (integer) from e.g. 123 to 0.123 without using strings. Can be any size integer. Not concerned about negative values.

```<code>Dim value As Integer = 123
Dim num As Decimal = "." & value.ToString
</code>```

It seems simple but I'm not sure how to do it using math. How can I convert without using strings?

答:
Here's one method:

```<code>Dim value As Integer = 123
Dim num As Decimal = value

While Math.Abs(num) >= 1
    num = num / 10
End While
</code>```

The Math.Abs takes care of negatives, so you could remove it as you say you're not concerned with them.

This also works:

```<code>Dim value as Integer = 123
Dim num as Decimal = value

num /= 10 ^ Math.Ceiling(Math.Log10(value))
</code>```

It's a little harder to see what's going on initially, but it basically finds the next power of 10 that is above the number, and divides by the 10^(that power)

Edit As per Craigs answer Math.Floor then add one works better than Math.Ceiling thus:

```<code>Dim value as Integer = 123
Dim num as Decimal = value

num /= 10 ^ (Math.Floor(Math.Log10(value)) + 1)
</code>```

Edit
I just did a quick performance comparison, and on my PC doing the While loop took 851ms, and the Log10 method took 158ms. That's for 1,000,000 iterations of each.

Body:
Looking for a way to convert a positive number (integer) from e.g. 123 to 0.123 without using strings. Can be any size integer. Not concerned about negative values.

Dim value As Integer = 123
Dim num As Decimal = "." & value.ToString

It seems simple but I'm not sure how to do it using math. How can I convert without using strings?

Body:
Here's one method:

Dim value As Integer = 123
Dim num As Decimal = value

While Math.Abs(num) >= 1
    num = num / 10
End While

The Math.Abs takes care of negatives, so you could remove it as you say you're not concerned with them.

This also works:

Dim value as Integer = 123
Dim num as Decimal = value

num /= 10 ^ Math.Ceiling(Math.Log10(value))

It's a little harder to see what's going on initially, but it basically finds the next power of 10 that is above the number, and divides by the 10^(that power)

Edit As per Craigs answer Math.Floor then add one works better than Math.Ceiling thus:

Dim value as Integer = 123
Dim num as Decimal = value

num /= 10 ^ (Math.Floor(Math.Log10(value)) + 1)

Edit
I just did a quick performance comparison, and on my PC doing the While loop took 851ms, and the Log10 method took 158ms. That's for 1,000,000 iterations of each.


问:
Safari view in swiftui displaying empty view
Hi everyone I am trying to display safari view as full screen modal using ZStack

```<code>        ZStack
        {
            HStack
            {
                VStack
                {
                    Safari(url: url)
                }
            }
        }
        .edgesIgnoringSafeArea(.all)
        .offset(x: 0, y: self.modalPresented ? 0 : 5000)
</code>```

But the output I get is a white empty view. And also the navigation bar is still visible.
Can someone please help me explain what is going on?
https://i.stack.imgur.com/Qqd64.jpg

答:
This is how we call a url :

```<code>url = URL(string: "https://www.hackingwithswift.com")
UIApplication.shared.open(url)
</code>```

If you are using Scene delegate, then you should handle url first, so go to Scene delegate and add this fuction, if it does not exists already:

```<code>func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {

    guard let url = URLContexts.first?.url else {
        return
    }

    //Handle URL here
}
</code>```

Then you url call should be like this:

```<code>UIApplication.shared.open(url, options: [:], completionHandler: nil)
</code>```

Body:
Hi everyone I am trying to display safari view as full screen modal using ZStack

        ZStack
        {
            HStack
            {
                VStack
                {
                    Safari(url: url)
                }
            }
        }
        .edgesIgnoringSafeArea(.all)
        .offset(x: 0, y: self.modalPresented ? 0 : 5000)

But the output I get is a white empty view. And also the navigation bar is still visible.
Can someone please help me explain what is going on?
https://i.stack.imgur.com/Qqd64.jpg

Body:
This is how we call a url :

url = URL(string: "https://www.hackingwithswift.com")
UIApplication.shared.open(url)

If you are using Scene delegate, then you should handle url first, so go to Scene delegate and add this fuction, if it does not exists already:

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {

    guard let url = URLContexts.first?.url else {
        return
    }

    //Handle URL here
}

Then you url call should be like this:

UIApplication.shared.open(url, options: [:], completionHandler: nil)