问:
(populate dropdown in contact form 7 getting this error - Warning: array_keys() expects parameter 1 to be array, null given in
Ok where to start, I will try and explain as much as I can.

I am using wordpress with contact form 7 and I am trying to populate 3 dropdown items on the contact form, I found some code that I was able to use with no problem but the problem with this was that it was getting the information from a excel file, the file is now to big and will not run on my website anymore so I would like to get the information from my database now.

I have made a table in my database "vehicle_information" with 3 columns "vehicle_type", "vehicle_make", vehicle_model"

I have code in my functions.php and code in my footer to be able to use the cf7 shortcodes.

Code from funtions.php

```<code>function ajax_cf7_populate_values() {

//MySQLi information

$db_host     = '***';
$db_username = '***';
$db_password = '***';

$vehicles_makes_models = array();

//connect to mysqli database (Host/Username/Password)
$connection = mysqli_connect($db_host, $db_username, $db_password) or die('Error ' . mysqli_error());

//select MySQLi dabatase table
$vehicles_makes_models = mysqli_select_db($connection, 'vehicle_information') or die('Error ' . mysqli_error());

$sql = mysqli_query($connection, 'SELECT * FROM vehicle_type');

while($row = mysqli_fetch_array($sql)) {
$vehicles_makes_models[$row[0]][$row[1]][] = $row[2];   }

}

    // setup the initial array that will be returned to the the client side script as a JSON object.

$return_array = array(
        'vehicles' => array_keys($vehicles_makes_models),
        'makes' => array(),
        'models' => array(),
        'current_vehicle' => false,
        'current_make' => false
    );

    // collect the posted values from the submitted form

$vehicle = key_exists('vehicle', $_POST) ? $_POST['vehicle'] : false;
$make = key_exists('make', $_POST) ? $_POST['make'] : false;
$model = key_exists('model', $_POST) ? $_POST['model'] : false;

    // populate the $return_array with the necessary values

if ($vehicle) {
    $return_array['current_vehicle'] = $vehicle;
    $return_array['makes'] = array_keys($vehicles_makes_models[$vehicle]);
    if ($make) {
    $return_array['current_make'] = $make;
    $return_array['models'] = $vehicles_makes_models[$vehicle][$make];
    if ($model) {
            $return_array['current_model'] = $model;
        }
        }
    }

    // encode the $return_array as a JSON object and echo it

    echo json_encode($return_array);
    wp_die();

 // These action hooks are needed to tell WordPress that the cf7_populate_values() function needs to be called
 // if a script is POSTing the action : 'cf7_populate_values'

 add_action( 'wp_ajax_cf7_populate_values', 'ajax_cf7_populate_values' );
 add_action( 'wp_ajax_nopriv_cf7_populate_values', 'ajax_cf7_populate_values' );
</code>```

Code from my footer

```<code><script>
(function($) {

    // create references to the 3 dropdown fields for later use.

    var $vehicles_dd = $('[name="vehicles"]');
    var $makes_dd = $('[name="makes"]');
    var $models_dd = $('[name="models"]');

    // run the populate_fields function, and additionally run it every time a value changes

    populate_fields();
    $('select').change(function() {
        populate_fields();
    });

    function populate_fields() {

        var data = {

            // action needs to match the action hook part after wp_ajax_nopriv_ and wp_ajax_ in the server side script.

            'action' : 'cf7_populate_values',

            // pass all the currently selected values to the server side script.

            'vehicle' : $vehicles_dd.val(),
            'make' : $makes_dd.val(),
            'model' : $models_dd.val()
        };

        // call the server side script, and on completion, update all dropdown lists with the received values.

        $.post('<?php echo admin_url( 'admin-ajax.php' ) ?>', data, function(response) {
            all_values = response;

            $vehicles_dd.html('').append($('<option>').text(' -- choose vehicle -- '));
            $makes_dd.html('').append($('<option>').text(' -- choose make  -- '));
            $models_dd.html('').append($('<option>').text(' -- choose model -- '));

            $.each(all_values.vehicles, function() {
                $option = $("<option>").text(this).val(this);
                if (all_values.current_vehicle == this) {
                    $option.attr('selected','selected');
                }
                $vehicles_dd.append($option);
            });
            $.each(all_values.makes, function() {
                $option = $("<option>").text(this).val(this);
                if (all_values.current_make == this) {
                    $option.attr('selected','selected');
                }
                $makes_dd.append($option);
            });
            $.each(all_values.models, function() {
                $option = $("<option>").text(this).val(this);
                if (all_values.current_model == this) {
                    $option.attr('selected','selected');
                }
                $models_dd.append($option);
            });
        },'json');
    }

})( jQuery );
</code>```

The problem is I am still learning and this is the first time I have had to use this funtion.

and I am getting an error on my website

Warning: array_keys() expects parameter 1 to be array, null given in /customers/4/0/0/motobid.co.uk/httpd.www/wp-content/themes/storevilla-child/functions.php on line 38 {"vehicles":null,"makes":[],"models":[],"current_vehicle":false,"current_make":false}

any help would be very greatful.

Just like to say code was supplied by BDMW.

答:
Where you use the method array_keys(), instead of:

```<code>  $return_array['makes'] = array_keys($vehicles_makes_models[$vehicle]);
</code>```

Try this:

```<code>$return_array['makes'] = ! empty($vehicles_makes_models[$vehicle]) ? array_keys($vehicles_makes_models[$vehicle]) : [];
</code>```

From what I've read, the array_keys() has been an issue depending on php versions. Hope this helps!

Body:
Ok where to start, I will try and explain as much as I can.

I am using wordpress with contact form 7 and I am trying to populate 3 dropdown items on the contact form, I found some code that I was able to use with no problem but the problem with this was that it was getting the information from a excel file, the file is now to big and will not run on my website anymore so I would like to get the information from my database now.

I have made a table in my database "vehicle_information" with 3 columns "vehicle_type", "vehicle_make", vehicle_model"

I have code in my functions.php and code in my footer to be able to use the cf7 shortcodes.

Code from funtions.php

function ajax_cf7_populate_values() {

//MySQLi information

$db_host     = '***';
$db_username = '***';
$db_password = '***';

$vehicles_makes_models = array();

//connect to mysqli database (Host/Username/Password)
$connection = mysqli_connect($db_host, $db_username, $db_password) or die('Error ' . mysqli_error());

//select MySQLi dabatase table
$vehicles_makes_models = mysqli_select_db($connection, 'vehicle_information') or die('Error ' . mysqli_error());

$sql = mysqli_query($connection, 'SELECT * FROM vehicle_type');

while($row = mysqli_fetch_array($sql)) {
$vehicles_makes_models[$row[0]][$row[1]][] = $row[2];   }

}

    // setup the initial array that will be returned to the the client side script as a JSON object.

$return_array = array(
        'vehicles' => array_keys($vehicles_makes_models),
        'makes' => array(),
        'models' => array(),
        'current_vehicle' => false,
        'current_make' => false
    );

    // collect the posted values from the submitted form

$vehicle = key_exists('vehicle', $_POST) ? $_POST['vehicle'] : false;
$make = key_exists('make', $_POST) ? $_POST['make'] : false;
$model = key_exists('model', $_POST) ? $_POST['model'] : false;

    // populate the $return_array with the necessary values

if ($vehicle) {
    $return_array['current_vehicle'] = $vehicle;
    $return_array['makes'] = array_keys($vehicles_makes_models[$vehicle]);
    if ($make) {
    $return_array['current_make'] = $make;
    $return_array['models'] = $vehicles_makes_models[$vehicle][$make];
    if ($model) {
            $return_array['current_model'] = $model;
        }
        }
    }

    // encode the $return_array as a JSON object and echo it

    echo json_encode($return_array);
    wp_die();

 // These action hooks are needed to tell WordPress that the cf7_populate_values() function needs to be called
 // if a script is POSTing the action : 'cf7_populate_values'

 add_action( 'wp_ajax_cf7_populate_values', 'ajax_cf7_populate_values' );
 add_action( 'wp_ajax_nopriv_cf7_populate_values', 'ajax_cf7_populate_values' );

Code from my footer

Body:
Where you use the method array_keys(), instead of:

  $return_array['makes'] = array_keys($vehicles_makes_models[$vehicle]);

Try this:

$return_array['makes'] = ! empty($vehicles_makes_models[$vehicle]) ? array_keys($vehicles_makes_models[$vehicle]) : [];

From what I've read, the array_keys() has been an issue depending on php versions. Hope this helps!


来源: stackexchange

问:
Dependency Injection in ASP.NET Core Worker Service
I'm facing some dependency injection issues in .NET Core Worker Service.
Please see the below code in Program.cs file.

public static void Main(string[] args)
{
    Log.Logger = new LoggerConfiguration()
        .MinimumLevel.Debug()
        .MinimumLevel.Override("Microsof)t", LogEventLevel.Warning)
        .Enrich.FromLogContext()
        .WriteTo.File(@"C:\MyApp_Log\Log.txt")
        .CreateLogger();

    try
    {
        Log.Information("Starting up the service.");
        CreateHostBuilder(args).Build().Run();
        return;
    }
    catch (Exception ex)
    {
        Log.Fatal(ex, "There was a problem starting the service");
        return;
    }
    finally
    {
        Log.CloseAndFlush();
    }

}
public static IHostBuilder CreateHostBuilder(string[] args)
{

    return Host.CreateDefaultBuilder(args)
        .UseWindowsService()
        .ConfigureServices((hostContext, services) =>
        {

            services.AddScoped<IMyAppCoreService, MyAppCoreService>();

            services.AddDbContext<MyAppCSContext>(options => options.UseSqlServer("Data Source=xx.xxx.xx.xxx;Database=Mydb;User ID = sa;Password=mypassword"));

            services.AddHostedService<Worker>();
        })
        .UseSerilog();
}
```

<p>And please see below code for <code>Worker.cs</code> file</p>

```private readonly ILogger<Worker> _logger;
private readonly IMyAppCoreService _CoreService;

public Worker(ILogger<Worker> logger, IMyAppCoreService CoreService)
{
    _logger = logger;
    _CoreService = CoreService;
}
public override Task StartAsync(CancellationToken cancellationToken)
{
    _logger.LogInformation("The MyApp_CoreService has been Started...");
    return base.StartAsync(cancellationToken);
}
public override Task StopAsync(CancellationToken cancellationToken)
{
    _logger.LogInformation("The MyApp_CoreService has been stopped...");
    return base.StopAsync(cancellationToken);
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
    while (!stoppingToken.IsCancellationRequested)
    {
        _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
        _CoreService.CheckAndProcessResult();
        await Task.Delay(1000, stoppingToken);
    }
}
```

When I run the above query, I got the below query.

Error while validating the service descriptor

ServiceType: MyApp.CS.Business.Facade.IMyAppCoreService Lifetime: Scoped ImplementationType: MyApp.CS.Business.Services.MyAppCoreService': Unable to resolve service for type 'MyApp.CS.Data.Facade.ICommonRepository' while attempting to activate 'MyApp.CS.Business.Services.MyAppCoreService'.

Can you please tell me where I was done wrong?

EDIT: After i register all the interface with its class. then i got new error as follows.

Error while validating the service descriptor 'ServiceType: Microsoft.Extensions.Hosting.IHostedService Lifetime: Singleton ImplementationType: MyApp_CoreService.Worker': Cannot consume scoped service 'MyApp.CS.Business.Facade.IMyAppCoreService' from singleton 'Microsoft.Extensions.Hosting.IHostedService'.

答:
You injected the Serivce IMyAppCoreService as Scoped. Scoped Services can only be resolved by a ScopedServiceProvider.

My first guess is that you didn't mean to - you meant to inject your service as Singleton:

```<code>services.AddSingleton<IMyAppCoreService, MyAppCoreService>();
</code>```

This however might not work since you are using EF Core which injects its Context-like classes as scoped. You have two options:

Have EF Core inject its context class as transient. I would not suggest this as you will be responsible for disposing it. If you want to go through with it, this is how to do it (Startup.cs / Program.cs):

```<code>services.AddDbContext<YourContext>(opts => { ...config...}, ServiceLifetime.Transient);
</code>```

Create a scope manually:

Have an IServiceProvider property called ServiceProvider injected into Worker instead of your service.

in ExecuteAsync-Loop:

```<code>_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
using (var scope = ServiceProvider.CreateScope())
{
  scope.ServiceProvider.GetRequiredService<IMyAppCoreService>().CheckAndProcessResult();
}
await Task.Delay(1000, stoppingToken);
</code>```

This will neatly dispose every Loop's EFCore-Data Context Object and in my opinion is the cleanest option.

ContentLicense: CC BY-SA 4.0

Body:
I'm facing some dependency injection issues in .NET Core Worker Service.
Please see the below code in Program.cs file.

public static void Main(string[] args)
{
    Log.Logger = new LoggerConfiguration()
        .MinimumLevel.Debug()
        .MinimumLevel.Override("Microsof)t", LogEventLevel.Warning)
        .Enrich.FromLogContext()
        .WriteTo.File(@"C:\MyApp_Log\Log.txt")
        .CreateLogger();

    try
    {
        Log.Information("Starting up the service.");
        CreateHostBuilder(args).Build().Run();
        return;
    }
    catch (Exception ex)
    {
        Log.Fatal(ex, "There was a problem starting the service");
        return;
    }
    finally
    {
        Log.CloseAndFlush();
    }

}
public static IHostBuilder CreateHostBuilder(string[] args)
{

    return Host.CreateDefaultBuilder(args)
        .UseWindowsService()
        .ConfigureServices((hostContext, services) =>
        {

            services.AddScoped<IMyAppCoreService, MyAppCoreService>();

            services.AddDbContext<MyAppCSContext>(options => options.UseSqlServer("Data Source=xx.xxx.xx.xxx;Database=Mydb;User ID = sa;Password=mypassword"));

            services.AddHostedService<Worker>();
        })
        .UseSerilog();
}

And please see below code for Worker.cs file

private readonly ILogger<Worker> _logger;
private readonly IMyAppCoreService _CoreService;

public Worker(ILogger<Worker> logger, IMyAppCoreService CoreService)
{
    _logger = logger;
    _CoreService = CoreService;
}
public override Task StartAsync(CancellationToken cancellationToken)
{
    _logger.LogInformation("The MyApp_CoreService has been Started...");
    return base.StartAsync(cancellationToken);
}
public override Task StopAsync(CancellationToken cancellationToken)
{
    _logger.LogInformation("The MyApp_CoreService has been stopped...");
    return base.StopAsync(cancellationToken);
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
    while (!stoppingToken.IsCancellationRequested)
    {
        _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
        _CoreService.CheckAndProcessResult();
        await Task.Delay(1000, stoppingToken);
    }
}

When I run the above query, I got the below query.

Error while validating the service descriptor

ServiceType: MyApp.CS.Business.Facade.IMyAppCoreService Lifetime: Scoped ImplementationType: MyApp.CS.Business.Services.MyAppCoreService': Unable to resolve service for type 'MyApp.CS.Data.Facade.ICommonRepository' while attempting to activate 'MyApp.CS.Business.Services.MyAppCoreService'.

Can you please tell me where I was done wrong?

EDIT: After i register all the interface with its class. then i got new error as follows.

Error while validating the service descriptor 'ServiceType: Microsoft.Extensions.Hosting.IHostedService Lifetime: Singleton ImplementationType: MyApp_CoreService.Worker': Cannot consume scoped service 'MyApp.CS.Business.Facade.IMyAppCoreService' from singleton 'Microsoft.Extensions.Hosting.IHostedService'.

Body:
You injected the Serivce IMyAppCoreService as Scoped. Scoped Services can only be resolved by a ScopedServiceProvider.

My first guess is that you didn't mean to - you meant to inject your service as Singleton:

services.AddSingleton<IMyAppCoreService, MyAppCoreService>();

This however might not work since you are using EF Core which injects its Context-like classes as scoped. You have two options:

Have EF Core inject its context class as transient. I would not suggest this as you will be responsible for disposing it. If you want to go through with it, this is how to do it (Startup.cs / Program.cs):

services.AddDbContext<YourContext>(opts => { ...config...}, ServiceLifetime.Transient);

Create a scope manually:

Have an IServiceProvider property called ServiceProvider injected into Worker instead of your service.

in ExecuteAsync-Loop:

_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
using (var scope = ServiceProvider.CreateScope())
{
  scope.ServiceProvider.GetRequiredService<IMyAppCoreService>().CheckAndProcessResult();
}
await Task.Delay(1000, stoppingToken);

This will neatly dispose every Loop's EFCore-Data Context Object and in my opinion is the cleanest option.


问:
React Hook "useSelector" is called in function
I cannot figure out what going on with "useSelector" I need little help, please.

ERROR

React Hook "useSelector" is called in function "render_user" which is neither a React function component or a custom React Hook function

```<code>class Navigationbar extends Component {

  onLogoutClick = e => {
    e.preventDefault();
    this.props.logoutUser(); //this.props.
  };

  render() {
      const render_user = () => {

        const auth = useSelector(state => state.auth); Error Message is here
        //More Code Here
      );
    };
  }

</code>```

```<code>Navigationbar.propTypes = {
  logoutUser: PropTypes.func.isRequired,
  auth: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
  auth: state.auth
});

export default connect(
  mapStateToProps,
  { logoutUser }
)(Navigationbar);
</code>```

答: If you are using TypeScript and (obviously) a functional component. Make sure your component name begins with a capital letter and not a lowercase letter.</p>

Body:
I cannot figure out what going on with "useSelector" I need little help, please.

ERROR

React Hook "useSelector" is called in function "render_user" which is neither a React function component or a custom React Hook function

class Navigationbar extends Component {

  onLogoutClick = e => {
    e.preventDefault();
    this.props.logoutUser(); //this.props.
  };

  render() {
      const render_user = () => {

        const auth = useSelector(state => state.auth); Error Message is here
        //More Code Here
      );
    };
  }

Navigationbar.propTypes = {
  logoutUser: PropTypes.func.isRequired,
  auth: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
  auth: state.auth
});

export default connect(
  mapStateToProps,
  { logoutUser }
)(Navigationbar);


问:
What is the best way to write to a file in a parallel thread in Java?
I have a program that performs lots of calculations and reports them to a file frequently. I know that frequent write operations can slow a program down a lot, so to avoid it I'd like to have a second thread dedicated to the writing operations.

Right now I'm doing it with this class I wrote (the impatient can skip to the end of the question):

```<code>public class ParallelWriter implements Runnable {

    private File file;
    private BlockingQueue<Item> q;
    private int indentation;

    public ParallelWriter( File f ){
        file = f;
        q = new LinkedBlockingQueue<Item>();
        indentation = 0;
    }

    public ParallelWriter append( CharSequence str ){
        try {
            CharSeqItem item = new CharSeqItem();
            item.content = str;
            item.type = ItemType.CHARSEQ;
            q.put(item);
            return this;
        } catch (InterruptedException ex) {
            throw new RuntimeException( ex );
        }
    }

    public ParallelWriter newLine(){
        try {
            Item item = new Item();
            item.type = ItemType.NEWLINE;
            q.put(item);
            return this;
        } catch (InterruptedException ex) {
            throw new RuntimeException( ex );
        }
    }

    public void setIndent(int indentation) {
        try{
            IndentCommand item = new IndentCommand();
            item.type = ItemType.INDENT;
            item.indent = indentation;
            q.put(item);
        } catch (InterruptedException ex) {
            throw new RuntimeException( ex );
        }
    }

    public void end(){
        try {
            Item item = new Item();
            item.type = ItemType.POISON;
            q.put(item);
        } catch (InterruptedException ex) {
            throw new RuntimeException( ex );
        }
    }

    public void run() {

        BufferedWriter out = null;
        Item item = null;

        try{
            out = new BufferedWriter( new FileWriter( file ) );
            while( (item = q.take()).type != ItemType.POISON ){
                switch( item.type ){
                    case NEWLINE:
                        out.newLine();
                        for( int i = 0; i < indentation; i++ )
                            out.append("   ");
                        break;
                    case INDENT:
                        indentation = ((IndentCommand)item).indent;
                        break;
                    case CHARSEQ:
                        out.append( ((CharSeqItem)item).content );
                }
            }
        } catch (InterruptedException ex){
            throw new RuntimeException( ex );
        } catch  (IOException ex) {
            throw new RuntimeException( ex );
        } finally {
            if( out != null ) try {
                out.close();
            } catch (IOException ex) {
                throw new RuntimeException( ex );
            }
        }
    }

    private enum ItemType {
        CHARSEQ, NEWLINE, INDENT, POISON;
    }
    private static class Item {
        ItemType type;
    }
    private static class CharSeqItem extends Item {
        CharSequence content;
    }
    private static class IndentCommand extends Item {
        int indent;
    }
}
</code>```

And then I use it by doing:

```<code>ParallelWriter w = new ParallelWriter( myFile );
new Thread(w).start();

/// Lots of
w.append(" things ").newLine();
w.setIndent(2);
w.newLine().append(" more things ");

/// and finally
w.end();
</code>```

While this works perfectly well, I'm wondering:
Is there a better way to accomplish this?

答:
Your basic approach looks fine. I would structure the code as follows:

    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.IOException;
    import java.io.Writer;
    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.LinkedBlockingQueue;
    import java.util.concurrent.TimeUnit;

    public interface FileWriter {
        FileWriter append(CharSequence seq);

        FileWriter indent(int indent);

        void close();
    }

    class AsyncFileWriter implements FileWriter, Runnable {
        private final File file;
        private final Writer out;
        private final BlockingQueue<Item> queue = new LinkedBlockingQueue<Item>();
        private volatile boolean started = false;
        private volatile boolean stopped = false;

        public AsyncFileWriter(File file) throws IOException {
            this.file = file;
            this.out = new BufferedWriter(new java.io.FileWriter(file));
        }

        public FileWriter append(CharSequence seq) {
            if (!started) {
                throw new IllegalStateException("open() call expected before append()");
            }
            try {
                queue.put(new CharSeqItem(seq));
            } catch (InterruptedException ignored) {
            }
            return this;
        }

        public FileWriter indent(int indent) {
            if (!started) {
                throw new IllegalStateException("open() call expected before append()");
            }
            try {
                queue.put(new IndentItem(indent));
            } catch (InterruptedException ignored) {
            }
            return this;
        }

        public void open() {
            this.started = true;
            new Thread(this).start();
        }

        public void run() {
            while (!stopped) {
                try {
                    Item item = queue.poll(100, TimeUnit.MICROSECONDS);
                    if (item != null) {
                        try {
                            item.write(out);
                        } catch (IOException logme) {
                        }
                    }
                } catch (InterruptedException e) {
                }
            }
            try {
                out.close();
            } catch (IOException ignore) {
            }
        }

        public void close() {
            this.stopped = true;
        }

        private static interface Item {
            void write(Writer out) throws IOException;
        }

        private static class CharSeqItem implements Item {
            private final CharSequence sequence;

            public CharSeqItem(CharSequence sequence) {
                this.sequence = sequence;
            }

            public void write(Writer out) throws IOException {
                out.append(sequence);
            }
        }

        private static class IndentItem implements Item {
            private final int indent;

            public IndentItem(int indent) {
                this.indent = indent;
            }

            public void write(Writer out) throws IOException {
                for (int i = 0; i < indent; i++) {
                    out.append(" ");
                }
            }
        }
    }
```

If you do not want to write in a separate thread (maybe in a test?), you can have an implementation of FileWriter which calls append on the Writer in the caller thread.

ContentLicense: CC BY-SA 3.0

Body:
I have a program that performs lots of calculations and reports them to a file frequently. I know that frequent write operations can slow a program down a lot, so to avoid it I'd like to have a second thread dedicated to the writing operations.

Right now I'm doing it with this class I wrote (the impatient can skip to the end of the question):

public class ParallelWriter implements Runnable {

    private File file;
    private BlockingQueue<Item> q;
    private int indentation;

    public ParallelWriter( File f ){
        file = f;
        q = new LinkedBlockingQueue<Item>();
        indentation = 0;
    }

    public ParallelWriter append( CharSequence str ){
        try {
            CharSeqItem item = new CharSeqItem();
            item.content = str;
            item.type = ItemType.CHARSEQ;
            q.put(item);
            return this;
        } catch (InterruptedException ex) {
            throw new RuntimeException( ex );
        }
    }

    public ParallelWriter newLine(){
        try {
            Item item = new Item();
            item.type = ItemType.NEWLINE;
            q.put(item);
            return this;
        } catch (InterruptedException ex) {
            throw new RuntimeException( ex );
        }
    }

    public void setIndent(int indentation) {
        try{
            IndentCommand item = new IndentCommand();
            item.type = ItemType.INDENT;
            item.indent = indentation;
            q.put(item);
        } catch (InterruptedException ex) {
            throw new RuntimeException( ex );
        }
    }

    public void end(){
        try {
            Item item = new Item();
            item.type = ItemType.POISON;
            q.put(item);
        } catch (InterruptedException ex) {
            throw new RuntimeException( ex );
        }
    }

    public void run() {

        BufferedWriter out = null;
        Item item = null;

        try{
            out = new BufferedWriter( new FileWriter( file ) );
            while( (item = q.take()).type != ItemType.POISON ){
                switch( item.type ){
                    case NEWLINE:
                        out.newLine();
                        for( int i = 0; i < indentation; i++ )
                            out.append("   ");
                        break;
                    case INDENT:
                        indentation = ((IndentCommand)item).indent;
                        break;
                    case CHARSEQ:
                        out.append( ((CharSeqItem)item).content );
                }
            }
        } catch (InterruptedException ex){
            throw new RuntimeException( ex );
        } catch  (IOException ex) {
            throw new RuntimeException( ex );
        } finally {
            if( out != null ) try {
                out.close();
            } catch (IOException ex) {
                throw new RuntimeException( ex );
            }
        }
    }

    private enum ItemType {
        CHARSEQ, NEWLINE, INDENT, POISON;
    }
    private static class Item {
        ItemType type;
    }
    private static class CharSeqItem extends Item {
        CharSequence content;
    }
    private static class IndentCommand extends Item {
        int indent;
    }
}

And then I use it by doing:

ParallelWriter w = new ParallelWriter( myFile );
new Thread(w).start();

/// Lots of
w.append(" things ").newLine();
w.setIndent(2);
w.newLine().append(" more things ");

/// and finally
w.end();

While this works perfectly well, I'm wondering:
Is there a better way to accomplish this?

Body:
Your basic approach looks fine. I would structure the code as follows:

    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.IOException;
    import java.io.Writer;
    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.LinkedBlockingQueue;
    import java.util.concurrent.TimeUnit;

    public interface FileWriter {
        FileWriter append(CharSequence seq);

        FileWriter indent(int indent);

        void close();
    }

    class AsyncFileWriter implements FileWriter, Runnable {
        private final File file;
        private final Writer out;
        private final BlockingQueue<Item> queue = new LinkedBlockingQueue<Item>();
        private volatile boolean started = false;
        private volatile boolean stopped = false;

        public AsyncFileWriter(File file) throws IOException {
            this.file = file;
            this.out = new BufferedWriter(new java.io.FileWriter(file));
        }

        public FileWriter append(CharSequence seq) {
            if (!started) {
                throw new IllegalStateException("open() call expected before append()");
            }
            try {
                queue.put(new CharSeqItem(seq));
            } catch (InterruptedException ignored) {
            }
            return this;
        }

        public FileWriter indent(int indent) {
            if (!started) {
                throw new IllegalStateException("open() call expected before append()");
            }
            try {
                queue.put(new IndentItem(indent));
            } catch (InterruptedException ignored) {
            }
            return this;
        }

        public void open() {
            this.started = true;
            new Thread(this).start();
        }

        public void run() {
            while (!stopped) {
                try {
                    Item item = queue.poll(100, TimeUnit.MICROSECONDS);
                    if (item != null) {
                        try {
                            item.write(out);
                        } catch (IOException logme) {
                        }
                    }
                } catch (InterruptedException e) {
                }
            }
            try {
                out.close();
            } catch (IOException ignore) {
            }
        }

        public void close() {
            this.stopped = true;
        }

        private static interface Item {
            void write(Writer out) throws IOException;
        }

        private static class CharSeqItem implements Item {
            private final CharSequence sequence;

            public CharSeqItem(CharSequence sequence) {
                this.sequence = sequence;
            }

            public void write(Writer out) throws IOException {
                out.append(sequence);
            }
        }

        private static class IndentItem implements Item {
            private final int indent;

            public IndentItem(int indent) {
                this.indent = indent;
            }

            public void write(Writer out) throws IOException {
                for (int i = 0; i < indent; i++) {
                    out.append(" ");
                }
            }
        }
    }

If you do not want to write in a separate thread (maybe in a test?), you can have an implementation of FileWriter which calls append on the Writer in the caller thread.


问:
node server.js not responding
I'm pretty new to node and I'm trying to create a simple server for my website but when I type in node server.js in command prompt nothing happens.

```<code>var http = require("http");
http.createServer(function(request, response) {
       response.writeHead(200, {"Content-Type": "text/plain"});
       response.write("It's alive!");
       response.end();
}).listen(3000);
</code>```

This is what I see when I try to run my server.js file:

I'm fairly certain my code is right, is there anything else I'm doing wrong?

答:
You only need to hit the URL http://localhost:3000.

The server is already started after you hit the command "node server.js" and you will get the output - "It's alive!" because of this line present in your code: response.write("It's alive!");

Title: node server.js not responding

Body:
I'm pretty new to node and I'm trying to create a simple server for my website but when I type in node server.js in command prompt nothing happens.

var http = require("http");
http.createServer(function(request, response) {
       response.writeHead(200, {"Content-Type": "text/plain"});
       response.write("It's alive!");
       response.end();
}).listen(3000);

This is what I see when I try to run my server.js file:

I'm fairly certain my code is right, is there anything else I'm doing wrong?


问:
How to use Jenkins parameters in a shell script
I want to use the parameters that we define in the Jenkins job as arguments to the shell commands in the same job.

I have created a parameterized build with the following parameters:

```<code>high.version: 234
low.version: 220
</code>```

I want to use these variables as arguments for the build's shell script:

```<code>/bin/bash /hai/mycode/scripts/run_script.sh high.version
</code>```

How do I these parameters in the same job?

答:
It is not a good practice to have dot(.) in your parameters. You should either choose highVersion OR high_version as your param names.

As per your question, it seems that you're working with a Freestyle job but many devs coming here would also be interested in the Pipeline syntax as well, so I'm giving a solution to use params in Jenkins pipeline DSL.
There are two ways you can use Jenkins parameters in the Jenkins Pipeline shell script -

As a Shell parameter

```<code>stage('Test'){
  sh "/bin/bash /hai/mycode/scripts/run_script.sh $highVersion"
}
</code>```

As a Groovy parameter

```<code>stage('Test'){
  sh "/bin/bash /hai/mycode/scripts/run_script.sh ${params.highVersion}"
}
</code>```

I would recommend to use a second method, as we're using groovy as a pipeline DSL.

Body:
I want to use the parameters that we define in the Jenkins job as arguments to the shell commands in the same job.

I have created a parameterized build with the following parameters:

high.version: 234
low.version: 220

I want to use these variables as arguments for the build's shell script:

/bin/bash /hai/mycode/scripts/run_script.sh high.version

How do I these parameters in the same job?

Body:
It is not a good practice to have dot(.) in your parameters. You should either choose highVersion OR high_version as your param names.

As per your question, it seems that you're working with a Freestyle job but many devs coming here would also be interested in the Pipeline syntax as well, so I'm giving a solution to use params in Jenkins pipeline DSL.
There are two ways you can use Jenkins parameters in the Jenkins Pipeline shell script -

As a Shell parameter

stage('Test'){
  sh "/bin/bash /hai/mycode/scripts/run_script.sh $highVersion"
}

As a Groovy parameter

stage('Test'){
  sh "/bin/bash /hai/mycode/scripts/run_script.sh ${params.highVersion}"
}

I would recommend to use a second method, as we're using groovy as a pipeline DSL.


问:
Count categorical levels broken down into columns of aggregated table
I have a data.table containing a categorial variable and I am looking for an efficient way to count its categories in an aggregated table, whereas each category is broken down into columns.

Here's my data:

```<code>library(data.table)
DT <- data.table(x = c(1, 1, 2, 1, 1, 1, 3, 3, 3, 2, 2),
                 y = c("A", "A", "B", "A", "A", "B", "B", "B", "A", "C"))
> DT
    x y
 1: 1 A
 2: 1 A
 3: 2 B
 4: 1 A
 5: 1 A
 6: 1 B
 7: 3 B
 8: 3 B
 9: 3 A
10: 2 A
11: 2 C

</code>```

Now I want to aggregate DT by x and receive a data.table with columns named after each category found in y, displaying the corresponding frequency:

```<code>   x A B C
1: 1 4 1 NA
2: 2 1 1 1
3: 3 1 2 NA
</code>```

So far I only managed to solve this problem 'manually' by creating aggregations for each category, e.g. DT[y == "A", .N, by = x] and merging them together with a left join. I grazed the entire internet unsuccessfully for a much more dynamic solution such as a function that simply delivers the desired result just like:

```<code>DT1 <- aggfunc(DT, var = "y", by = "x")
</code>```

答:
Sure there is. You basically want to reshape your counts:

```<code># count cases
aggregated <- DT[, .N, by = .(y, x)]
# reshape to desired result
dcast(aggregated, formula = x ~ y, value.var = "N")
   x A B  C
1: 1 4 1 NA
2: 2 1 1  1
3: 3 1 2 NA
</code>```

or, to directly write the function you desire:

```<code>aggfunc <- function(DT, var = "y", by = "x"){
  DT[, .N, by = c(var, by)]
  dcast(aggregated, formula = paste(by, "~", var), value.var = "N")
}

aggfunc(DT)
   x A B  C
1: 1 4 1 NA
2: 2 1 1  1
3: 3 1 2 NA
</code>```

Body:
I have a data.table containing a categorial variable and I am looking for an efficient way to count its categories in an aggregated table, whereas each category is broken down into columns.

Here's my data:

library(data.table)
DT <- data.table(x = c(1, 1, 2, 1, 1, 1, 3, 3, 3, 2, 2),
                 y = c("A", "A", "B", "A", "A", "B", "B", "B", "A", "C"))
> DT
    x y
 1: 1 A
 2: 1 A
 3: 2 B
 4: 1 A
 5: 1 A
 6: 1 B
 7: 3 B
 8: 3 B
 9: 3 A
10: 2 A
11: 2 C

Now I want to aggregate DT by x and receive a data.table with columns named after each category found in y, displaying the corresponding frequency:

   x A B C
1: 1 4 1 NA
2: 2 1 1 1
3: 3 1 2 NA

So far I only managed to solve this problem 'manually' by creating aggregations for each category, e.g. DT[y == "A", .N, by = x] and merging them together with a left join. I grazed the entire internet unsuccessfully for a much more dynamic solution such as a function that simply delivers the desired result just like:

DT1 <- aggfunc(DT, var = "y", by = "x")

Body:
Sure there is. You basically want to reshape your counts:

# count cases
aggregated <- DT[, .N, by = .(y, x)]
# reshape to desired result
dcast(aggregated, formula = x ~ y, value.var = "N")
   x A B  C
1: 1 4 1 NA
2: 2 1 1  1
3: 3 1 2 NA

or, to directly write the function you desire:

aggfunc <- function(DT, var = "y", by = "x"){
  DT[, .N, by = c(var, by)]
  dcast(aggregated, formula = paste(by, "~", var), value.var = "N")
}

aggfunc(DT)
   x A B  C
1: 1 4 1 NA
2: 2 1 1  1
3: 3 1 2 NA


问:
prestashop 1.7 new module
I have a problem in prestashop 1.7, when I load the form.tpl in my module I can not do a setAction. What I need is that when I continue in the payment I open a new sale with a payment platform and in prestashop in platform carge the validation I leave the code. help please

main file of the prestashop module

```<code>         public function hookPaymentOptions($params) {

        if (!$this->active) {
            return;
        }

        $this->smarty->assign(
                $this->getPaymentApiVars()
        );

        $apiPayement = new PaymentOption();
        $apiPayement->setModuleName($this->name)
                ->setLogo($this->context->link->getBaseLink().'/modules/hhpayment/views/img/pago.jpg')
//                ->setCallToActionText($this->l(''))
                //Définition d'un formulaire personnalisé
                ->setForm($this->fetch('module:hhpayment/views/templates/hook/payment_api_form.tpl'))
                ->setAdditionalInformation($this->fetch('module:hhpayment/views/templates/hook/displayPaymentApi.tpl'))
                 ->setAction($this->context->link->getModuleLink($this->name, 'validation', array(), true));

        return [$apiPayement];
    }
</code>```

this is the form.tpl that I charge this without the method but it is by tests

```<code><form action="{$payment_url}" target="_blank" >
    <div class="form-group">
        {* choix du mode de carte *}
        {l s='please choose your card type' mod='hhpayment'}
            <div class="radio">
                <label>
                    <input type="radio" name="cb_type" value="mastercard" id="cb_type1" checked="checked" /> Pago internacional
                </label>
            </div>
            <div class="radio">
                <label>
                    <input type="radio" name="cb_type" id="cb_type2" value="visa"/> Pago Nacional
                </label>
            </div>
    </div>
    {* Informations pour l'api *}
    <input type="hidden" name="success_url" value="{$success_url}" />
    <input type="hidden" name="error_url" value="{$error_url}" />
    <input type="hidden" name="id_cart" value="{$id_cart}" />
    <input type="hidden" name="cart_total" value="{$cart_total}" />
    <input type="hidden" name="id_customer" value="{$id_customer}" />
</form>
</code>```

and this is the validation file

```<code>class hhpaymentvalidationModuleFrontController extends ModuleFrontController
{

    /**
     * Validation du paiement standard
     * Puis redirection vers la page de succès de commande
     */
    public function postProcess()
    {
         $cart = $this->context->cart;

       $this->abrir("http://davivienda.com");

        if ($cart->id_customer == 0 || $cart->id_address_delivery == 0 || $cart->id_address_invoice == 0 || !$this->module->active) {
            Tools::redirect('index.php?controller=order&step=1');
        }

        $customer = new Customer($cart->id_customer);

        if (!Validate::isLoadedObject($customer)) {
            Tools::redirect('index.php?controller=order&step=1');
        }

        $currency = $this->context->currency;
        $total = (float)$cart->getOrderTotal(true, Cart::BOTH);

        //La command passe directement en statut payé
        $this->module->validateOrder((int)$cart->id, Configuration::get('PS_OS_PAYMENT'), $total, $this->module->displayName, null, array(), (int)$currency->id, false, $customer->secure_key);
        Tools::redirect('index.php?controller=order-confirmation&id_cart='.(int)$cart->id.'&id_module='.(int)$this->module->id.'&id_order='.$this->module->currentOrder.'&key='.$customer->secure_key);
    }

    public function abrir($param)
    {
        echo" <script> window.open(URL,'ventana1,'width=300,height=300,scrollbars=NO')</script> ";

    }

}
</code>```

答:
I was able to find a solution to this problem, I don't know if it is the correct one, but it already works for me:

The postProcess method passes it to the main and the validation.php file passes it to the same folder where the main file is.

Then it is time to modify the validation.php file which was changed to the same directory as main, this file should be as follows.

It should be imported

```<code>require_once dirname(__FILE__) . '/config/config.inc.php';
require_once dirname(__FILE__) . '/main.php';
</code>```

Then to avoid a kernel error the following code snippet must be implemented

```<code>global $kernel;
if(!$kernel){
    require_once _PS_ROOT_DIR_.'/app/AppKernel.php';
    $kernel = new \AppKernel('prod', false);
    $kernel->boot();
}
</code>```

After this, it is necessary to implement the logic and receive the parameters by get that the payment screen will return to us after the payment is made, once this data is received, the cart must be recovered and the data sent to the function that was migrated to the main file

```<code>ob_start();
    $context = Context::getContext();

if (is_null($context->cart)) {
    $context->cart = new Cart($context->cookie->id_cart);
}
if (is_null($context->cart->id_currency)) {
    $context->cart->id_currency = $context->cookie->id_currency;
}

$cart = $context->cart;
$customer = new Customer($cart->id_customer);
$currency = $cart->id_currency;
$total = (float)$cart->getOrderTotal(true, Cart::BOTH);
$object = new filemain();

$order = $object->methodCreateInMain($cart->id, Configuration::get('PS_OS_PAYMENT'), $total, $currency, $customer->secure_key);
</code>```

Basically the previous code in validation.php retrieves the cart data and sends it by parameter to the function that was passed to main, where the order will be validated and created.

It should be noted that the return url after payment must be ulrCommerce/module/validation.php

The above worked perfectly for me and is a solution based on various blogs and forums viewed

Title: prestashop 1.7 new module

Body:
I have a problem in prestashop 1.7, when I load the form.tpl in my module I can not do a setAction. What I need is that when I continue in the payment I open a new sale with a payment platform and in prestashop in platform carge the validation I leave the code. help please

main file of the prestashop module

         public function hookPaymentOptions($params) {

        if (!$this->active) {
            return;
        }

        $this->smarty->assign(
                $this->getPaymentApiVars()
        );

        $apiPayement = new PaymentOption();
        $apiPayement->setModuleName($this->name)
                ->setLogo($this->context->link->getBaseLink().'/modules/hhpayment/views/img/pago.jpg')
//                ->setCallToActionText($this->l(''))
                //Définition d'un formulaire personnalisé
                ->setForm($this->fetch('module:hhpayment/views/templates/hook/payment_api_form.tpl'))
                ->setAdditionalInformation($this->fetch('module:hhpayment/views/templates/hook/displayPaymentApi.tpl'))
                 ->setAction($this->context->link->getModuleLink($this->name, 'validation', array(), true));

        return [$apiPayement];
    }

this is the form.tpl that I charge this without the method but it is by tests

<form action="{$payment_url}" target="_blank" >

        {* choix du mode de carte *}
        {l s='please choose your card type' mod='hhpayment'}

                    <input type="radio" name="cb_type" value="mastercard" id="cb_type1" checked="checked" /> Pago internacional

                    <input type="radio" name="cb_type" id="cb_type2" value="visa"/> Pago Nacional

    {* Informations pour l'api *}
    <input type="hidden" name="success_url" value="{$success_url}" />
    <input type="hidden" name="error_url" value="{$error_url}" />
    <input type="hidden" name="id_cart" value="{$id_cart}" />
    <input type="hidden" name="cart_total" value="{$cart_total}" />
    <input type="hidden" name="id_customer" value="{$id_customer}" />
</form>

and this is the validation file

class hhpaymentvalidationModuleFrontController extends ModuleFrontController
{

    /**
     * Validation du paiement standard
     * Puis redirection vers la page de succès de commande
     */
    public function postProcess()
    {
         $cart = $this->context->cart;

       $this->abrir("http://davivienda.com");

        if ($cart->id_customer == 0 || $cart->id_address_delivery == 0 || $cart->id_address_invoice == 0 || !$this->module->active) {
            Tools::redirect('index.php?controller=order&step=1');
        }

        $customer = new Customer($cart->id_customer);

        if (!Validate::isLoadedObject($customer)) {
            Tools::redirect('index.php?controller=order&step=1');
        }

        $currency = $this->context->currency;
        $total = (float)$cart->getOrderTotal(true, Cart::BOTH);

        //La command passe directement en statut payé
        $this->module->validateOrder((int)$cart->id, Configuration::get('PS_OS_PAYMENT'), $total, $this->module->displayName, null, array(), (int)$currency->id, false, $customer->secure_key);
        Tools::redirect('index.php?controller=order-confirmation&id_cart='.(int)$cart->id.'&id_module='.(int)$this->module->id.'&id_order='.$this->module->currentOrder.'&key='.$customer->secure_key);
    }

    public function abrir($param)
    {
        echo"  ";

    }

}

Body:
I was able to find a solution to this problem, I don't know if it is the correct one, but it already works for me:

The postProcess method passes it to the main and the validation.php file passes it to the same folder where the main file is.

Then it is time to modify the validation.php file which was changed to the same directory as main, this file should be as follows.

It should be imported

require_once dirname(__FILE__) . '/config/config.inc.php';
require_once dirname(__FILE__) . '/main.php';

Then to avoid a kernel error the following code snippet must be implemented

global $kernel;
if(!$kernel){
    require_once _PS_ROOT_DIR_.'/app/AppKernel.php';
    $kernel = new \AppKernel('prod', false);
    $kernel->boot();
}

After this, it is necessary to implement the logic and receive the parameters by get that the payment screen will return to us after the payment is made, once this data is received, the cart must be recovered and the data sent to the function that was migrated to the main file

ob_start();
    $context = Context::getContext();

if (is_null($context->cart)) {
    $context->cart = new Cart($context->cookie->id_cart);
}
if (is_null($context->cart->id_currency)) {
    $context->cart->id_currency = $context->cookie->id_currency;
}

$cart = $context->cart;
$customer = new Customer($cart->id_customer);
$currency = $cart->id_currency;
$total = (float)$cart->getOrderTotal(true, Cart::BOTH);
$object = new filemain();

$order = $object->methodCreateInMain($cart->id, Configuration::get('PS_OS_PAYMENT'), $total, $currency, $customer->secure_key);

Basically the previous code in validation.php retrieves the cart data and sends it by parameter to the function that was passed to main, where the order will be validated and created.

It should be noted that the return url after payment must be ulrCommerce/module/validation.php

The above worked perfectly for me and is a solution based on various blogs and forums viewed


问:
What does &H57 represent and how can I translate it for C#?
I'm trying to convert old VB.NET code into C# and I'm not sure about the current line and what it means really.

VB.NET:

```<code>Const REQUEST_EFI As Byte = &H57
</code>```

What would this be in c#?  I tried:

```<code>const byte request_efi = &H57;
</code>```

But it says

"H57 is not part of the current
  context".

First of all, how is &H57 a byte?  Second, it seems that the & operator has a different representation in this context aside from concatenation.  Third obviously being, how the heck do I re-write this for C#? lol.  Thanks!

答: I guess it is a hexadecimal number. The syntax for that would be 0x57 in C#.

Body:
I'm trying to convert old VB.NET code into C# and I'm not sure about the current line and what it means really.

VB.NET:

Const REQUEST_EFI As Byte = &H57

What would this be in c#?  I tried:

const byte request_efi = &H57;

But it says

"H57 is not part of the current
  context".

First of all, how is &H57 a byte?  Second, it seems that the & operator has a different representation in this context aside from concatenation.  Third obviously being, how the heck do I re-write this for C#? lol.  Thanks!


问:
What is the hierarchy for Python module imports?
Lets assume I have Python module in a directory and in the same directory I have a Python script that uses this module somehow.

```<code>wdir
├── module
│   └── module_stuff
└── script.py
</code>```

If I execute this file in a python environment where the module is not installed everything works fine as Python imports the module from it's source code.

The question is: if I install the module in this Python environment and continue executing the script the same way as before, will Python import the module from what was installed or from the source code? What is the hyerarchy Python follows to search for each import?

Why does it matter: If I have a script repeatedly calling other Python scripts and modify the source code of the module during this execution, then there will be results that used the old version of the module and the new version as well, or even worse, executions may be missed if a bug is inserted into the module code. But this would be solved if created a development env separated from the testing env.

答:
It seems to depend on sys.path

Quoting https://docs.python.org/3/tutorial/modules.html#the-module-search-path:

When a module named spam is imported, the interpreter first searches for a built-in module with that name. If not found, it then searches for a file named spam.py in a list of directories given by the variable sys.path. sys.path is initialized from these locations: [edit: presumably in this order]

The directory containing the input script (or the current directory when no file is specified).

PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).

The installation-dependent default.

which goes on to say

After initialization, Python programs can modify sys.path.

which suggests to me that anything could in theory happen :-/

I guess module_stuff doesn't have the same name as a builtin so that rules out the first of these.

As you probably know, Python won't import the same module twice in a single run. Perhaps you can test it by making a small change to module/module_stuff and running again.

Body:
Lets assume I have Python module in a directory and in the same directory I have a Python script that uses this module somehow.

wdir
├── module
│   └── module_stuff
└── script.py

If I execute this file in a python environment where the module is not installed everything works fine as Python imports the module from it's source code.

The question is: if I install the module in this Python environment and continue executing the script the same way as before, will Python import the module from what was installed or from the source code? What is the hyerarchy Python follows to search for each import?

Why does it matter: If I have a script repeatedly calling other Python scripts and modify the source code of the module during this execution, then there will be results that used the old version of the module and the new version as well, or even worse, executions may be missed if a bug is inserted into the module code. But this would be solved if created a development env separated from the testing env.


问:
Looping a stratification function on segmented data
I didn't use a regular loop because it is a package and the segments are not going to be "numeric"  I want to run this package separately on each segment of the data.  Example code of me trying and getting "NULL".  The real issue is that I am automating this process and this single case is just an example.

```<code>frame<-read.delim('F:/SonoT/2019/Sampling_Frame.txt', header=T, sep="\t")

attach(frame)
names(frame)

datapre<-split(frame$Billing.Amount,frame$CustomerName)
**data<-as.double(frame$Billing.Amount)**

n_min=6
n_max=11
Ls_max=2

lapply(datapre, function(x){
  for (n in n_min:n_max){
    res<-strata.LH(**data**, n, CV = NULL, Ls, certain = NULL,
                   alloc = list(q1 = 0.5, q2 = 0, q3 = 0.5), takenone = 1,
                   bias.penalty = 1, takeall = 1, rh = rep(1, Ls),
                   model = c("none"),
                   model.control = list(), initbh = NULL,
                   algo = c("Kozak"), algo.control = list()
    )
  }
})
</code>```

In Bold is where I believe the most fundamental problems are.  I split the data so as.double isn't going to work so simply and I'm trying to iterate and automate so singular processes aren't super handy.   I'm in search of the right solution to help me segment the data then perform this packaged function on all segments of the original frame.  Thanks!!!

(Note Sampling_Frame is just 3 columns of code, one Identifier, the second used to segment, the third is numeric which will be used to stratify)
Below is an the data from the txt file "Sampling_Frame" for a minimal working example

```<code>     JOB    CustomerName    Billing Amount
18-1938 LMT 844874.4
19-1376 PJR 537137.73
19-1352 PJR 488824.38
19-1021 PJR 470939.12
19-1798 PJR 457664.7
19-2088 PJR 297236
19-1677 PJR 289618.08
19-1375 PJR 247639.19
19-1365 PJR 219043.63
18-1823 PJR 209307.34
19-1818 PJR 200998.77
19-1817 PJR 190823.68
19-1276 PJR 181501.92
19-1815 PJR 176378.26
19-1032 LMT 148820.26
19-1084 LMT 138196.34
19-1067 LMT 136659.39
19-1741 LMT 124441.03
19-1083 LMT 123765.9
19-1831 LMT 123562.68
19-2051 LMT 123165.17
19-1514 LMT 118154.4
19-1358 PJR 116789.4
19-1489 PJR 110486.26
19-1535 LMT 107360.87
19-1495 LMT 106515.48
19-1498 LMT 106515.48
19-1497 LMT 106515.48
19-1214 LMT 105693.57
19-1380 LMT 102042.72
19-1724 LMT 99093.09
19-1392 LMT 95834.17
19-1491 RNF 95309.95
19-1626 RNF 92679.44
19-1311 RNF 92531.28
19-1541 RNF 91908
19-1023 RNF 91560.24
19-1132 RNF 90712.05
19-1476 RNF 87297.18
19-1478 RNF 87297.18
19-1341 RNF 86788.79
19-1007 RNF 85865.83
19-1043 RNF 85664.88
19-1044 RNF 85664.88
19-1182 PJR 85664.88
19-1099 PJR 83723.56
19-1085 PJR 83518.56
19-1597 PJR 79901.25
19-1183 PJR 79827.21
19-1299 RNF 79098.81
19-1371 RNF 75446.28
18-1893 RNF 75364.76
18-1938 LMT 535420.2907
19-1376 PJR 665971.1543
19-1352 PJR 113937.3254
19-1021 PJR 901412.9552
19-1798 PJR 180870.6582
19-2088 PJR 459256.6056
19-1677 PJR 786567.9076
19-1375 PJR 107233.7503
19-1365 PJR 529049.9652
18-1823 PJR 93935.11101
19-1818 PJR 781140.9755
19-1817 PJR 626540.2303
19-1276 PJR 994367.0361
19-1815 PJR 248037.5789
19-1032 LMT 591415.5152
19-1084 LMT 955234.6192
19-1067 LMT 985639.924
19-1741 LMT 41756.03667
19-1083 LMT 422216.9353
19-1831 LMT 514984.3071
19-2051 LMT 921309.5568
19-1514 LMT 836335.2603
19-1358 PJR 606062.0096
19-1489 PJR 490173.5946
19-1535 LMT 980659.3195
19-1495 LMT 302602.6893
19-1498 LMT 669464.3852
19-1497 LMT 354799.0461
19-1214 LMT 589567.4014
19-1380 LMT 210924.1892
19-1724 LMT 76164.3439
19-1392 LMT 208655.3566
19-1491 RNF 509698.2722
19-1626 RNF 622272.0624
19-1311 RNF 259806.3957
19-1541 RNF 839041.7736
19-1023 RNF 796422.9877
19-1132 RNF 106002.6997
19-1476 RNF 551992.2614
19-1478 RNF 735833.4733
19-1341 RNF 110942.0706
19-1007 RNF 586964.3845
19-1043 RNF 39630.9694
19-1044 RNF 121490.1144
19-1182 PJR 134848.2189
19-1099 PJR 869101.0679
19-1085 PJR 486720.2974
19-1597 PJR 319308.3749
19-1183 PJR 747375.1898
19-1299 RNF 408166.5797
19-1371 RNF 989657.9436
18-1893 RNF 621918.6124
</code>```

答:
Because you are running a for loop within the lapply function, you effectively do not return any object and therefore NULL is returned. Also, you never use the x variable passed into lapply call. Also, attach is redundant and as.double is not necessary if Billing.Amount column is a numeric type. Per ?as.double docs:

as.double is a generic function. It is identical to as.numeric.

To resolve, consider converting for loop to another lapply to capture all iterations between n_min and n_max and pass x into strata.LH call. Of course assign outer lapply to an new list object which will have length equal to datapre and each element of new object will contain 6 results of strata.LH (for n varying between 6-11).

```<code>output_list <- lapply(datapre, function(x){
  res <- lapply(n_min:n_max, function(n)
    strata.LH(x, n, CV = NULL, Ls, certain = NULL,
              alloc = list(q1 = 0.5, q2 = 0, q3 = 0.5), takenone = 1,
              bias.penalty = 1, takeall = 1, rh = rep(1, Ls),
              model = c("none"),
              model.control = list(), initbh = NULL,
              algo = c("Kozak"), algo.control = list())
  )

  return(res)
})
</code>```

Body:
I didn't use a regular loop because it is a package and the segments are not going to be "numeric"  I want to run this package separately on each segment of the data.  Example code of me trying and getting "NULL".  The real issue is that I am automating this process and this single case is just an example.

frame<-read.delim('F:/SonoT/2019/Sampling_Frame.txt', header=T, sep="\t")

attach(frame)
names(frame)

datapre<-split(frame$Billing.Amount,frame$CustomerName)
**data<-as.double(frame$Billing.Amount)**

n_min=6
n_max=11
Ls_max=2

lapply(datapre, function(x){
  for (n in n_min:n_max){
    res<-strata.LH(**data**, n, CV = NULL, Ls, certain = NULL,
                   alloc = list(q1 = 0.5, q2 = 0, q3 = 0.5), takenone = 1,
                   bias.penalty = 1, takeall = 1, rh = rep(1, Ls),
                   model = c("none"),
                   model.control = list(), initbh = NULL,
                   algo = c("Kozak"), algo.control = list()
    )
  }
})

In Bold is where I believe the most fundamental problems are.  I split the data so as.double isn't going to work so simply and I'm trying to iterate and automate so singular processes aren't super handy.   I'm in search of the right solution to help me segment the data then perform this packaged function on all segments of the original frame.  Thanks!!!

(Note Sampling_Frame is just 3 columns of code, one Identifier, the second used to segment, the third is numeric which will be used to stratify)
Below is an the data from the txt file "Sampling_Frame" for a minimal working example

     JOB    CustomerName    Billing Amount
18-1938 LMT 844874.4
19-1376 PJR 537137.73
19-1352 PJR 488824.38
19-1021 PJR 470939.12
19-1798 PJR 457664.7
19-2088 PJR 297236
19-1677 PJR 289618.08
19-1375 PJR 247639.19
19-1365 PJR 219043.63
18-1823 PJR 209307.34
19-1818 PJR 200998.77
19-1817 PJR 190823.68
19-1276 PJR 181501.92
19-1815 PJR 176378.26
19-1032 LMT 148820.26
19-1084 LMT 138196.34
19-1067 LMT 136659.39
19-1741 LMT 124441.03
19-1083 LMT 123765.9
19-1831 LMT 123562.68
19-2051 LMT 123165.17
19-1514 LMT 118154.4
19-1358 PJR 116789.4
19-1489 PJR 110486.26
19-1535 LMT 107360.87
19-1495 LMT 106515.48
19-1498 LMT 106515.48
19-1497 LMT 106515.48
19-1214 LMT 105693.57
19-1380 LMT 102042.72
19-1724 LMT 99093.09
19-1392 LMT 95834.17
19-1491 RNF 95309.95
19-1626 RNF 92679.44
19-1311 RNF 92531.28
19-1541 RNF 91908
19-1023 RNF 91560.24
19-1132 RNF 90712.05
19-1476 RNF 87297.18
19-1478 RNF 87297.18
19-1341 RNF 86788.79
19-1007 RNF 85865.83
19-1043 RNF 85664.88
19-1044 RNF 85664.88
19-1182 PJR 85664.88
19-1099 PJR 83723.56
19-1085 PJR 83518.56
19-1597 PJR 79901.25
19-1183 PJR 79827.21
19-1299 RNF 79098.81
19-1371 RNF 75446.28
18-1893 RNF 75364.76
18-1938 LMT 535420.2907
19-1376 PJR 665971.1543
19-1352 PJR 113937.3254
19-1021 PJR 901412.9552
19-1798 PJR 180870.6582
19-2088 PJR 459256.6056
19-1677 PJR 786567.9076
19-1375 PJR 107233.7503
19-1365 PJR 529049.9652
18-1823 PJR 93935.11101
19-1818 PJR 781140.9755
19-1817 PJR 626540.2303
19-1276 PJR 994367.0361
19-1815 PJR 248037.5789
19-1032 LMT 591415.5152
19-1084 LMT 955234.6192
19-1067 LMT 985639.924
19-1741 LMT 41756.03667
19-1083 LMT 422216.9353
19-1831 LMT 514984.3071
19-2051 LMT 921309.5568
19-1514 LMT 836335.2603
19-1358 PJR 606062.0096
19-1489 PJR 490173.5946
19-1535 LMT 980659.3195
19-1495 LMT 302602.6893
19-1498 LMT 669464.3852
19-1497 LMT 354799.0461
19-1214 LMT 589567.4014
19-1380 LMT 210924.1892
19-1724 LMT 76164.3439
19-1392 LMT 208655.3566
19-1491 RNF 509698.2722
19-1626 RNF 622272.0624
19-1311 RNF 259806.3957
19-1541 RNF 839041.7736
19-1023 RNF 796422.9877
19-1132 RNF 106002.6997
19-1476 RNF 551992.2614
19-1478 RNF 735833.4733
19-1341 RNF 110942.0706
19-1007 RNF 586964.3845
19-1043 RNF 39630.9694
19-1044 RNF 121490.1144
19-1182 PJR 134848.2189
19-1099 PJR 869101.0679
19-1085 PJR 486720.2974
19-1597 PJR 319308.3749
19-1183 PJR 747375.1898
19-1299 RNF 408166.5797
19-1371 RNF 989657.9436
18-1893 RNF 621918.6124

Body:
Because you are running a for loop within the lapply function, you effectively do not return any object and therefore NULL is returned. Also, you never use the x variable passed into lapply call. Also, attach is redundant and as.double is not necessary if Billing.Amount column is a numeric type. Per ?as.double docs:

as.double is a generic function. It is identical to as.numeric.

To resolve, consider converting for loop to another lapply to capture all iterations between n_min and n_max and pass x into strata.LH call. Of course assign outer lapply to an new list object which will have length equal to datapre and each element of new object will contain 6 results of strata.LH (for n varying between 6-11).

output_list <- lapply(datapre, function(x){
  res <- lapply(n_min:n_max, function(n)
    strata.LH(x, n, CV = NULL, Ls, certain = NULL,
              alloc = list(q1 = 0.5, q2 = 0, q3 = 0.5), takenone = 1,
              bias.penalty = 1, takeall = 1, rh = rep(1, Ls),
              model = c("none"),
              model.control = list(), initbh = NULL,
              algo = c("Kozak"), algo.control = list())
  )

  return(res)
})


问:
Oracle APEX style APEX_ITEM Dynamic form elements
I followed the instructions from this post on how to create dynamic items in APEX. The documentation is clear on how to create the item but I cannot figure out how to make the item look like native APEX items.

I have attempted copying different CSS classes that I can see attached to the native items, but for the life of me I cannot get my dynamically created form elements to look and act the same.

Any help would be greatly appreciated.

答:
This should help:

```<code>with
    TP_ORDEM_SERV_REC as (
        select  C.ID_FUNCAO,
                C.QT_EXEC
        from    TB_ORDEM_SERV_REC C
        where   C.ID_ORDEM_SERV = :P922_ID_ORDEM_SERV
        and     C.NUM_TAR = :P922_NUM_TAR)

select  A.DESC_SUPLEMENT FUNCAO,
        '<div class="t-Form-fieldContainer t-Form-fieldContainer--floatingLabel lto'||A.ID_SUPLEMENT||' apex-item-wrapper apex-item-wrapper--text-field" id="it_'||A.ID_SUPLEMENT||'_CONTAINER">'||
            '<div class="t-Form-labelContainer">'||
                '<label for="it_'||A.ID_SUPLEMENT||'" id="it_'||A.ID_SUPLEMENT||'_LABEL" class="t-Form-label">Quant. Exec.</label>'||
            '</div>'||
            '<div class="t-Form-inputContainer">'||
                '<div class="t-Form-itemWrapper">'||
                    '<input type="hidden" name="f01" value="'||A.ID_SUPLEMENT||'"  />'||
                    '<input type="text" name="f02" id="it_'||A.ID_SUPLEMENT||'"  class="text_field apex-item-text" value="'||A.QT_EXEC||'" size="1" maxlength="2">'||
                '</div>'||
                '<span id="it_'||A.ID_SUPLEMENT||'_error_placeholder" class="a-Form-error" data-template-id="'||A.ID_SUPLEMENT||'_ET"></span>'||
            '</div>'||
        '</div>' QT_EXEC
from    TB_SUPLEMENT A,
        TB_USUARIO B,
        TP_ORDEM_SERV_REC C
where   A.FLAG_CTRL = 15
and     B.ID_OFICINA = :P922_ID_OFICINA
and     A.ID_SUPLEMENT = B.ID_FUNCAO
and     B.ID_FUNCAO = C.ID_FUNCAO (+)
group by A.DESC_SUPLEMENT,A.ID_SUPLEMENT,C.QT_EXEC
</code>```

Then, just use apex_application.g_f to manipulate the result in the process as normal.

Body:
This should help:

with
    TP_ORDEM_SERV_REC as (
        select  C.ID_FUNCAO,
                C.QT_EXEC
        from    TB_ORDEM_SERV_REC C
        where   C.ID_ORDEM_SERV = :P922_ID_ORDEM_SERV
        and     C.NUM_TAR = :P922_NUM_TAR)

select  A.DESC_SUPLEMENT FUNCAO,
        '<div class="t-Form-fieldContainer t-Form-fieldContainer--floatingLabel lto'||A.ID_SUPLEMENT||' apex-item-wrapper apex-item-wrapper--text-field" id="it_'||A.ID_SUPLEMENT||'_CONTAINER">'||
            '<div class="t-Form-labelContainer">'||
                '<label for="it_'||A.ID_SUPLEMENT||'" id="it_'||A.ID_SUPLEMENT||'_LABEL" class="t-Form-label">Quant. Exec.</label>'||
            '</div>'||
            '<div class="t-Form-inputContainer">'||
                '<div class="t-Form-itemWrapper">'||
                    '<input type="hidden" name="f01" value="'||A.ID_SUPLEMENT||'"  />'||
                    '<input type="text" name="f02" id="it_'||A.ID_SUPLEMENT||'"  class="text_field apex-item-text" value="'||A.QT_EXEC||'" size="1" maxlength="2">'||
                '</div>'||
                '<span id="it_'||A.ID_SUPLEMENT||'_error_placeholder" class="a-Form-error" data-template-id="'||A.ID_SUPLEMENT||'_ET"></span>'||
            '</div>'||
        '</div>' QT_EXEC
from    TB_SUPLEMENT A,
        TB_USUARIO B,
        TP_ORDEM_SERV_REC C
where   A.FLAG_CTRL = 15
and     B.ID_OFICINA = :P922_ID_OFICINA
and     A.ID_SUPLEMENT = B.ID_FUNCAO
and     B.ID_FUNCAO = C.ID_FUNCAO (+)
group by A.DESC_SUPLEMENT,A.ID_SUPLEMENT,C.QT_EXEC

Then, just use apex_application.g_f to manipulate the result in the process as normal.


问:
Reading Database File from External Storage
So, this program downloads a file from firebase storage,
my downloading code is:

```<code>private void downloadFiles(Context context, String fileName, String destinationDirectory, String url) {
    DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
    Uri uri = Uri.parse(url);
    DownloadManager.Request request = new DownloadManager.Request(uri);

    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
    request.setDestinationInExternalFilesDir(context, String.valueOf(destinationDirectory), fileName);

    downloadManager.enqueue(request);
}

public void downloading(final String name) {
    downloadRef = storage.getInstance().getReference().child(name);
    downloadRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
        @Override
        public void onSuccess(Uri uri) {
            String url = uri.toString();
            downloadFiles(Main2Activity.this, name,  getApplicationContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), url);
        }
    }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            Toast.makeText(Main2Activity.this, "Failed!!!", Toast.LENGTH_LONG).show();
        }
    });
}
</code>```

and then I want to use this database so I tried to open it with:

```<code>database = SQLiteDatabase.openDatabase(myPath, null, 0);
</code>```

How can I solve this one? It would be really helpful guys.

答:
I thought your problem was accessibility.
That's why I brought a activity back to get permission from the user.
You test this code</p>

```<code>listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
                        && ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(MainActivity.this, new String[] {Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
                } else {
                    Intent intent = new Intent(MainActivity.this, Main2Activity.class);
                    intent.putExtra("name", arrayList.get(position));
                    startActivity(intent);
                }

            }
        });
</code>```

Body:
So, this program downloads a file from firebase storage,
my downloading code is:

private void downloadFiles(Context context, String fileName, String destinationDirectory, String url) {
    DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
    Uri uri = Uri.parse(url);
    DownloadManager.Request request = new DownloadManager.Request(uri);

    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
    request.setDestinationInExternalFilesDir(context, String.valueOf(destinationDirectory), fileName);

    downloadManager.enqueue(request);
}

public void downloading(final String name) {
    downloadRef = storage.getInstance().getReference().child(name);
    downloadRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
        @Override
        public void onSuccess(Uri uri) {
            String url = uri.toString();
            downloadFiles(Main2Activity.this, name,  getApplicationContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), url);
        }
    }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            Toast.makeText(Main2Activity.this, "Failed!!!", Toast.LENGTH_LONG).show();
        }
    });
}

and then I want to use this database so I tried to open it with:

database = SQLiteDatabase.openDatabase(myPath, null, 0);

How can I solve this one? It would be really helpful guys.

Body:
I thought your problem was accessibility.
That's why I brought a activity back to get permission from the user.
You test this code

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
                        && ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(MainActivity.this, new String[] {Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
                } else {
                    Intent intent = new Intent(MainActivity.this, Main2Activity.class);
                    intent.putExtra("name", arrayList.get(position));
                    startActivity(intent);
                }

            }
        });


问:
Shared Whiteboard with AS3. Code
I am building a shared whiteboard and I cannot get the shared whiteboard to be shared. I have successfully created a shared method and I see the shared object in the Admin Console that it is there and connected but can't see the drawing on a different browser. I am posting the entire actionscript code. Please help me if you can. Will be greatly appreciated. I am really new to actionscript. </p>

```<code>package
{
 import flash.display.Sprite;
 import flash.display.MovieClip;
 import flash.net.SharedObject;
 import flash.events.NetStatusEvent;
 import flash.events.SyncEvent;
 import flash.net.NetConnection;
 import flash.events.MouseEvent;

 public class PenSOmc extends Sprite
 {
  private var drawing_so:SharedObject;
  private var nc:NetConnection;
  private var good:Boolean;
  private var isDrawing:Boolean;
  private var penMC:MovieClip;
  private var rpenMC:MovieClip;
    // Mouse Coordinates
    private var startX:int;
    private var startY:int;
    private var endX:int;
    private var endY:int;

  // Remote mouse coordinates
    private var rstartX:int;
    private var rstartY:int;
    private var rendX:int;
    private var rendY:int;

  public function PenSOmc ()
  {
   penMC = new MovieClip();
   var rtmpNow:String="rtmp://localhost/whiteboard";
   nc=new NetConnection;
   nc.connect(rtmpNow);
   nc.addEventListener(NetStatusEvent.NET_STATUS,doSO);
   stage.addEventListener(MouseEvent.MOUSE_DOWN, startDrawing);
   stage.addEventListener(MouseEvent.MOUSE_MOVE, drawing);
   stage.addEventListener(MouseEvent.MOUSE_UP, stopDrawing);
   addChild(penMC);
  }

  private function doSO (e:NetStatusEvent):void
  {
   good=e.info.code == "NetConnection.Connect.Success";
   if (good)
   {
    //Shared object
    drawing_so = SharedObject.getRemote("draw",nc.uri,false);
    drawing_so.connect(nc);
    drawing_so.addEventListener(SyncEvent.SYNC,doUpdate);
    trace("Connected");
   }
  }

  private function doUpdate (se:SyncEvent):void
  {

   for (var cl:int = 0; cl < se.changeList.length; cl++)
   {

    trace(se.changeList[cl].code);

    switch(se.changeList[cl].code)
    {
     case "clear":
      break;
     case "success":
      break;
     case "change":
      //var points:String = sharedObject.data.points;

      var pointsArray:Array = drawing_so.data.points.split(/,/);
      var rstartX:int = int(pointsArray[0]);
      var rstartY:int = int(pointsArray[1]);
      var rendX:int = int(pointsArray[2]);
      var rendY:int = int(pointsArray[3]);
      rpenMC = new MovieClip();
      rpenMC.graphics.moveTo(rstartX,rstartY);
      rpenMC.graphics.lineTo(rendX,rendY);
      addChild(rpenMC);
      break;
    }
   }
  }

  private function startDrawing (e:MouseEvent):void
  {
   trace("Start drawing");
   isDrawing = true;
   var penTipSize:uint = 1;
   var penColor:Number = 0x000000;
   penMC.graphics.lineStyle(penTipSize, penColor, 1.0);
   startX = mouseX;
   startY = mouseY;
   penMC.graphics.moveTo(startX, startY);
  }

  private function stopDrawing (e:MouseEvent):void
  {
   trace("Stop drawing");
   isDrawing = false;
  }

  private function drawing (e:MouseEvent):void
  {
   if (isDrawing)
   {
    trace("Drawing");
    endX = mouseX;
    endY = mouseY;
    drawing_so.setProperty("points",startX + "," + startY + "," + endX + "," + endY);
    penMC.graphics.lineTo(endX, endY);
   }
  }

 }

}
</code>```

答:
This works:</p>

```<code>package
{
 import flash.display.Sprite;
 import flash.display.MovieClip;
 import flash.net.SharedObject;
 import flash.events.NetStatusEvent;
 import flash.events.SyncEvent;
 import flash.net.NetConnection;
 import flash.events.MouseEvent;

 public class PenSOmc extends Sprite
 {
  private var drawing_so:SharedObject;
  private var nc:NetConnection;
  private var good:Boolean;
  private var isDrawing:Boolean;
  private var penMC:MovieClip;
  private var rpenMC:MovieClip;
    // Mouse Coordinates
    private var startX:int;
    private var startY:int;
    private var endX:int;
    private var endY:int;

  // Remote mouse coordinates
    private var rstartX:int;
    private var rstartY:int;
    private var rendX:int;
    private var rendY:int;

  public function PenSOmc ()
  {
   penMC = new MovieClip();
   var rtmpNow:String="rtmp://localhost/whiteboard";
   nc=new NetConnection;
   nc.connect(rtmpNow);
   nc.addEventListener(NetStatusEvent.NET_STATUS,doSO);
   stage.addEventListener(MouseEvent.MOUSE_DOWN, startDrawing);
   stage.addEventListener(MouseEvent.MOUSE_MOVE, drawing);
   stage.addEventListener(MouseEvent.MOUSE_UP, stopDrawing);
   addChild(penMC);
  }

  private function doSO (e:NetStatusEvent):void
  {
   good=e.info.code == "NetConnection.Connect.Success";
   if (good)
   {
    //Shared object
    drawing_so = SharedObject.getRemote("draw",nc.uri,false);
    drawing_so.connect(nc);
    drawing_so.addEventListener(SyncEvent.SYNC,doUpdate);
    trace("Connected");
   }
  }

  private function doUpdate (se:SyncEvent):void
  {

   for (var cl:int = 0; cl < se.changeList.length; cl++)
   {

    switch(se.changeList[cl].code)
    {
     case "clear":
      break;
     case "success":
      break;
     case "change":
      //var points:String = sharedObject.data.points;
      var pointsArray:Array = drawing_so.data.points.split(/,/);
      var rstartX:int = int(pointsArray[0]);
      var rstartY:int = int(pointsArray[1]);
      var rendX:int = int(pointsArray[2]);
      var rendY:int = int(pointsArray[3]);
      //penMC.graphics.moveTo(rstartX,rstartY);
      penMC.graphics.lineTo(rendX,rendY);
      break;
    }
   }
  }

  private function startDrawing (e:MouseEvent):void
  {
   trace("Start drawing");
   isDrawing = true;
   var penTipSize:uint = 1;
   var penColor:Number = 0x000000;
   penMC.graphics.lineStyle(penTipSize, penColor, 1.0);
   startX = mouseX;
   startY = mouseY;
   penMC.graphics.moveTo(startX, startY);
  }

  private function stopDrawing (e:MouseEvent):void
  {
   trace("Stop drawing");
   isDrawing = false;
  }

  private function drawing (e:MouseEvent):void
  {
   if (isDrawing)
   {
    trace("Drawing");
    endX = mouseX;
    endY = mouseY;
    drawing_so.setProperty("points",startX + "," + startY + "," + endX + "," + endY);
    penMC.graphics.lineTo(endX, endY);
   }
  }

 }

}
</code>```

ContentLicense: CC BY-SA 2.5

Title: Shared Whiteboard with AS3. Code

Body:
I am building a shared whiteboard and I cannot get the shared whiteboard to be shared. I have successfully created a shared method and I see the shared object in the Admin Console that it is there and connected but can't see the drawing on a different browser. I am posting the entire actionscript code. Please help me if you can. Will be greatly appreciated. I am really new to actionscript.

package
{
 import flash.display.Sprite;
 import flash.display.MovieClip;
 import flash.net.SharedObject;
 import flash.events.NetStatusEvent;
 import flash.events.SyncEvent;
 import flash.net.NetConnection;
 import flash.events.MouseEvent;

 public class PenSOmc extends Sprite
 {
  private var drawing_so:SharedObject;
  private var nc:NetConnection;
  private var good:Boolean;
  private var isDrawing:Boolean;
  private var penMC:MovieClip;
  private var rpenMC:MovieClip;
    // Mouse Coordinates
    private var startX:int;
    private var startY:int;
    private var endX:int;
    private var endY:int;

  // Remote mouse coordinates
    private var rstartX:int;
    private var rstartY:int;
    private var rendX:int;
    private var rendY:int;

  public function PenSOmc ()
  {
   penMC = new MovieClip();
   var rtmpNow:String="rtmp://localhost/whiteboard";
   nc=new NetConnection;
   nc.connect(rtmpNow);
   nc.addEventListener(NetStatusEvent.NET_STATUS,doSO);
   stage.addEventListener(MouseEvent.MOUSE_DOWN, startDrawing);
   stage.addEventListener(MouseEvent.MOUSE_MOVE, drawing);
   stage.addEventListener(MouseEvent.MOUSE_UP, stopDrawing);
   addChild(penMC);
  }

  private function doSO (e:NetStatusEvent):void
  {
   good=e.info.code == "NetConnection.Connect.Success";
   if (good)
   {
    //Shared object
    drawing_so = SharedObject.getRemote("draw",nc.uri,false);
    drawing_so.connect(nc);
    drawing_so.addEventListener(SyncEvent.SYNC,doUpdate);
    trace("Connected");
   }
  }

  private function doUpdate (se:SyncEvent):void
  {

   for (var cl:int = 0; cl < se.changeList.length; cl++)
   {

    trace(se.changeList[cl].code);

    switch(se.changeList[cl].code)
    {
     case "clear":
      break;
     case "success":
      break;
     case "change":
      //var points:String = sharedObject.data.points;

      var pointsArray:Array = drawing_so.data.points.split(/,/);
      var rstartX:int = int(pointsArray[0]);
      var rstartY:int = int(pointsArray[1]);
      var rendX:int = int(pointsArray[2]);
      var rendY:int = int(pointsArray[3]);
      rpenMC = new MovieClip();
      rpenMC.graphics.moveTo(rstartX,rstartY);
      rpenMC.graphics.lineTo(rendX,rendY);
      addChild(rpenMC);
      break;
    }
   }
  }

  private function startDrawing (e:MouseEvent):void
  {
   trace("Start drawing");
   isDrawing = true;
   var penTipSize:uint = 1;
   var penColor:Number = 0x000000;
   penMC.graphics.lineStyle(penTipSize, penColor, 1.0);
   startX = mouseX;
   startY = mouseY;
   penMC.graphics.moveTo(startX, startY);
  }

  private function stopDrawing (e:MouseEvent):void
  {
   trace("Stop drawing");
   isDrawing = false;
  }

  private function drawing (e:MouseEvent):void
  {
   if (isDrawing)
   {
    trace("Drawing");
    endX = mouseX;
    endY = mouseY;
    drawing_so.setProperty("points",startX + "," + startY + "," + endX + "," + endY);
    penMC.graphics.lineTo(endX, endY);
   }
  }

 }

}

Body:
This works:

package
{
 import flash.display.Sprite;
 import flash.display.MovieClip;
 import flash.net.SharedObject;
 import flash.events.NetStatusEvent;
 import flash.events.SyncEvent;
 import flash.net.NetConnection;
 import flash.events.MouseEvent;

 public class PenSOmc extends Sprite
 {
  private var drawing_so:SharedObject;
  private var nc:NetConnection;
  private var good:Boolean;
  private var isDrawing:Boolean;
  private var penMC:MovieClip;
  private var rpenMC:MovieClip;
    // Mouse Coordinates
    private var startX:int;
    private var startY:int;
    private var endX:int;
    private var endY:int;

  // Remote mouse coordinates
    private var rstartX:int;
    private var rstartY:int;
    private var rendX:int;
    private var rendY:int;

  public function PenSOmc ()
  {
   penMC = new MovieClip();
   var rtmpNow:String="rtmp://localhost/whiteboard";
   nc=new NetConnection;
   nc.connect(rtmpNow);
   nc.addEventListener(NetStatusEvent.NET_STATUS,doSO);
   stage.addEventListener(MouseEvent.MOUSE_DOWN, startDrawing);
   stage.addEventListener(MouseEvent.MOUSE_MOVE, drawing);
   stage.addEventListener(MouseEvent.MOUSE_UP, stopDrawing);
   addChild(penMC);
  }

  private function doSO (e:NetStatusEvent):void
  {
   good=e.info.code == "NetConnection.Connect.Success";
   if (good)
   {
    //Shared object
    drawing_so = SharedObject.getRemote("draw",nc.uri,false);
    drawing_so.connect(nc);
    drawing_so.addEventListener(SyncEvent.SYNC,doUpdate);
    trace("Connected");
   }
  }

  private function doUpdate (se:SyncEvent):void
  {

   for (var cl:int = 0; cl < se.changeList.length; cl++)
   {

    switch(se.changeList[cl].code)
    {
     case "clear":
      break;
     case "success":
      break;
     case "change":
      //var points:String = sharedObject.data.points;
      var pointsArray:Array = drawing_so.data.points.split(/,/);
      var rstartX:int = int(pointsArray[0]);
      var rstartY:int = int(pointsArray[1]);
      var rendX:int = int(pointsArray[2]);
      var rendY:int = int(pointsArray[3]);
      //penMC.graphics.moveTo(rstartX,rstartY);
      penMC.graphics.lineTo(rendX,rendY);
      break;
    }
   }
  }

  private function startDrawing (e:MouseEvent):void
  {
   trace("Start drawing");
   isDrawing = true;
   var penTipSize:uint = 1;
   var penColor:Number = 0x000000;
   penMC.graphics.lineStyle(penTipSize, penColor, 1.0);
   startX = mouseX;
   startY = mouseY;
   penMC.graphics.moveTo(startX, startY);
  }

  private function stopDrawing (e:MouseEvent):void
  {
   trace("Stop drawing");
   isDrawing = false;
  }

  private function drawing (e:MouseEvent):void
  {
   if (isDrawing)
   {
    trace("Drawing");
    endX = mouseX;
    endY = mouseY;
    drawing_so.setProperty("points",startX + "," + startY + "," + endX + "," + endY);
    penMC.graphics.lineTo(endX, endY);
   }
  }

 }

}