React-native dynamic images with lots of images - react-native

I have an array of 150 buttons that link to 150 pictures, i need to show the picture once the button is pressed. The information for the buttons is stored in a JSON file. The pictures names are the ID's of the buttons, so 1.jpg, 2.jpg etc.
Now I am facing the problem that I can't write:
fish["image"] = {uri: "asset-library://" + fish.id + ".jpg"};
And the other solution with if statements does not work since I have so many options, any ideas?
Thanks so much

I had a similar problem. I built a function that contains a huge switch statement and has static requires for every case.
function getImage(id) {
switch(id) {
case 1:
return require('./img/1.jpg');
case 2:
return require('./img/2.jpg');
...
}
}
Now you can do
fish["image"] = getImage(fish.id);
I also had to use over 100 icons, so instead of writing the cases by hand, I built a script that generates the function automatically.

I had too this problem for a component I developed. I used base64 image in json file. But maybe it's not a good fit for you, I hope it can help.
<Image
style={styles.imgStyle}
source={{uri: CountryFlags[country.cca2]}}
/>
You can see it here : https://github.com/xcarpentier/react-native-country-picker-modal/blob/master/src/index.js#L137-L139
And if you have a folder with files on it, simply convert images like that :
#!/bin/sh
list=`ls ./flags | grep '[A-Z]'`
echo "{"
for item in $list
do
header="data:image/png;base64,"
img64=`ls ./flags/$item | xargs cat | base64`
echo ${item:0:2} :\'$header$img64\',
done
echo "}"

Related

Maya MEL scripting how to read from an intField

Forgive me for asking a basic question on stack overflow, but documentation and simple guides on the mel scripting language have proved to be very hard to find.
In any case, I'm trying to write a simple mel script that automatically creates a low-poly railroad, just as a learning excercise. The general idea is that a popup window will appear asking for how many segments you want
I've managed to get the window to appear, but now I have a few additional questions.
Firstly, how do I read in the value from the intField when I hit the button that runs the main procedure? I can't find any relevant guides.
Second, I've noticed a new problem in which the main script (which I'm currently running with a default value) seems to be running multiple times. What I think is happening is that when I click the button, I hold it down a bit too long, and Maya registers this as me clicking the button multiple times. How can I modify the button so that It only registers one click when I click on it?
Here is my code:
/***
Auto-Railroad Creator and Rigger
***/
// This script creates a low-poly, rigged railroad thingy that an artist can move and twist into position.
//relevant variables:
//the number of ties
int $numSegments = 0;
//the procedure that actually creates the railroad
//Heads up, this procedure is NOT finished. I'm just trying to get the window stuff working before I move on to completing this.
global proc makeRails(int $segments)
{
//If the given length is zero, do nothing.
if ( $segments == 0) return;
///the code proper
CreatePolygonCube;
polyCube -w 1 -h 1 -d 1 -sx 1 -sy 1 -sz 1 -ax 0 1 0 -cuv 4 -ch 1;
// Result: pCube1 polyCube1 //
return;
}
//The procedure that opens the popup window which asks for details:
global proc jh_makeRail()
{
//delete window if it already exists
if (`window -q -ex jh_makeRail`) deleteUI jh_makeRail;
//main window
window -topEdge 30 -title "Create a low-poly rail segment"
-mxb false -s true -rtf false -mb false -mbv false -w 300 -h 440 jh_makeRail;
//window content
columnLayout -adjustableColumn true;
separator -w 240 -h 20;
text -label "Utility to automatically create a low-poly rig for a simple railroad segment";
separator -w 240 -h 25;
text -label "Rail segment length (measured by the number of ties):";
intField -minValue 0;
//How do I use the value of this intField?
separator -w 240 -h 20;
//Since I haven't figured out how to read in the value of the intField, I'm using a default value of 30.
button -label "Make Rail" -c "makeRails 30";
window -e -w 300 -h 500 jh_makeRail;
showWindow jh_makeRail;
}
//This here is supposed to be the "entry point" of the mel script, where the code starts doing things.
jh_makeRail;
So, good news. A kind person on reddit helped me solve the problem.
First, regarding the secondary procedure running twice... turns out I was wrong about that. It was making two cubes because I told it to.
I had believed that "CreatePolygonCube;" and "polyCube -w 1 -h 1 -d 1 -sx 1 -sy 1 -sz 1 -ax 0 1 0 -cuv 4 -ch 1;" were two parts of the same instruction, but they are actually two different ways to make a cube.
Next, regarding the primary question... Transfering the value from the intField to a global variable involves some sort of shuffling.
The code this person suggested is as follows:
{
//You need to declare existing global vars in like this, almost like you're importing them into the proc
global int $numSegments;
//Create field
string $myIntField = `intField -minValue 0`;
//build command string
string $cmd = "$numSegments = `intField -q -value " + $myIntField + "`";
//set change command
intField -edit -changeCommand $cmd $myIntField;
}
(This is a part of the window function, not the whole thing.)
The relevant thread is here:
https://www.reddit.com/r/Maya/comments/q1vz1i/i_need_help_with_mel_scripting/hfjpoh7/?context=3
global int $numSegments;
Yeah, don't do this :)
Use the optionVar MEL command instead!
// define some custom name for your global variable
string $myName = "railroad_num_segments";
// set your global var like so:
global void railroadSetNumSegments(int $num) {
optionVar -intVal "railroad_num_segments" $num;
}
// and query the value like so:
global int railroadGetNumSegments() {
// check to see if we have previously registered the optionVar
if(!`optionVar -exists "railroad_num_segments"`) {
// if the option doesn't exist, define a 'sensible' default here
railroadSetNumSegments(1);
}
// return the user preference
return `optionVar -q "railroad_num_segments"`;
}
The advantage of optionVar is that your user preference is now stored between Maya sessions.
Whenever you need the number of segments in your script, simply call railroadGetNumSegments().
You can also simplify the intField control to just:
intField -minValue 0 -value `railroadGetNumSegments` -changeCommand "railroadSetNumSegments #1";
Specifying #1 in the change command, will automatically query the controls value when it changes.
Also worth noting that there are actually 3 ways to create a polyCube in Maya. The entirely manual approach would be:
use createNode to create the polyCube node, and a mesh node.
use connectAttr to connect the outMesh attribute of the poly cube node, to the "inMesh" attribute on the mesh node.
use the sets command to add the mesh to the default shading group set.
use setAttr to set the polyCUbe node params to the desired values
That is in effect what the polyCube MEL command does internally.
The "CreatePolygonCube" command uses optionVar, to read all of the user preferences for the default widths/heights/num divisions etc; and then passes those parameters to the polyCube command.

perl6 Is there a way to do editable prompt input?

In bash shell, if you hit up or down arrows, the shell will show you your previous or next command that you entered, and you can edit those commands to be new shell commands.
In perl6, if you do
my $name = prompt("Enter name: ");
it will print "Enter name: " and then ask for input; is there a way to have perl6 give you a default value and then you just edit the default to be the new value. E.g.:
my $name = prompt("Your name:", "John Doe");
and it prints
Your name: John Doe
where the John Doe part is editable, and when you hit enter, the edited string is the value of $name.
https://docs.raku.org/routine/prompt does not show how to do it.
This is useful if you have to enter many long strings each of which is just a few chars different from others.
Thanks.
To get the editing part going, you could use the Linenoise module:
zef install Linenoise
(https://github.com/hoelzro/p6-linenoise)
Then, in your code, do:
use Linenoise;
sub prompt($p) {
my $l = linenoise $p;
linenoiseHistoryAdd($l);
$l
}
Then you can do your loop with prompt. Remember, basically all Perl 6 builtin functions can be overridden lexically. Now, how to fill in the original string, that I haven't figure out just yet. Perhaps the libreadline docs can help you with that.
Well by default, programs are completely unaware of their terminals.
You need your program to communicate with the terminal to do things like pre-fill an input line, and it's unreasonable to expect Perl 6 to handle something like this as part of the core language.
That said, your exact case is handled by the Readline library as long as you have a compatible terminal.
It doesn't look like the perl 6 Readline has pre-input hooks setup so you need to handle the callback and read loop yourself, unfortunately. Here's my rough attempt that does exactly what you want:
use v6;
use Readline;
sub prompt-prefill($question, $suggestion) {
my $rl = Readline.new;
my $answer;
my sub line-handler( Str $line ) {
rl_callback_handler_remove();
$answer = $line;
}
rl_callback_handler_install( "$question ", &line-handler );
$rl.insert-text($suggestion);
$rl.redisplay;
while (!$answer) {
$rl.callback-read-char();
}
return $answer;
}
my $name = prompt-prefill("What's your name?", "Bob");
say "Hi $name. Go away.";
If you are still set on using Linenoise, you might find the 'hints' feature good enough for your needs (it's used extensively by the redis-cli application if you want a demo). See the hint callback used with linenoiseSetHintsCallback in the linenoise example.c file. If that's not good enough you'll have to start digging into the guts of linenoise.
Another solution :
Use io-prompt
With that you can set a default value and even a default type:
my $a = ask( "Life, the universe and everything?", 42, type => Num );
Life, the universe and everything? [42]
Int $a = 42
You can install it with:
zef install IO::Prompt
However, if just a default value is not enough. Then it is better you use the approach Liz has suggested.

Printing barcode on odoo pos receipt

I need to print a barcode on Odoo (v8) pos receipt using posbox.
I tried like this :
<barcode encoding="CODE39"><t t-esc='receipt.coupon_code'/></barcode>
Result : Nothing is printed . But if I make a test like :
<barcode encoding="CODE39">*123456798*</barcode>
It prints the barcode.
I also tried like this without success:
<img t-att-src="'/report/barcode/?type=%s&value=%s&width=%s&height=%s' % ('CODE39', receipt.coupon_code, 600, 100)" style="width:300px;height:50px"/>
Any advice ?
Thanks a lot.
In fact,
<barcode encoding="CODE39"><t t-esc='receipt.coupon_code'/></barcode>
works perfectly...
The problem was the length of receipt.coupon_code.
For information, this coupon_code is randomly generated .
It prints successfully the barcode with an 8 digits code, starting and ending with "*" ( *12345678*, for example)
I created one receipt and I know how to write barcode in receipt for that you have to convert your barcode in image and then split it. You have to make changes in .xml file. Steps are as follow:
Convert this code in image using <img> tag after then split that like this:
<img t-if="field_name" t-att-src="'/report/barcode/?type=%s&value=%s&width=%s&height=%s&humanreadable=%s' % ('Code128', field_name.split(' ')[1], 600, 100, 1)" style="width:300px;height:50px"/>
Here field_name is that field of py where your barcode is stored.

Vim: Writing function skeleton

When writing new functions with Vim I always seem to have to do a bit of "manual" work.
x = Cursor position
If I start typing a function and insert a couple of curly braces and the end
function Apples() {x}
Then hit Enter, it obviously looks like this
function Apples() {
x}
Which results in me having to ESC,O in order to shift the closing curlybrace down.
While this may seem like a trivial matter, doing this over the last 5 months is getting bothersome, and I know there are plenty like me out there who knows there should be an elegant solution to this. I am open to plugin-suggestions.
You can use a simple mapping like this one (there are dozens of variants floating around SO and the web):
inoremap {} {<CR>}<C-o>O
You can also search www.vim.org for a dedicated plugin.
But I strongly recommend you to try a snippet-expansion plugin like Snipmate or UltiSnips. Both plugins follow the same model but they have slightly different snippet syntaxes and features. It works like that:
you type a trigger:
fun
you hit <Tab> and you get the following with function_name in select mode:
function [function_name]() {
}
you type your desired name:
function Apples|() {
}
you hit <Tab> to place the cursor between the parentheses:
function Apples(|) {
}
you hit <Tab> again to place the cursor on the line below with the correct indentation:
function Apples() {
|
}
With lh-bracket (in C or C++ mode), when you hit enter whilst in between two brackets, the newlines you are expecting are inserted.
The idea is to test for: getline(".")[col(".")-2:col(".")-1]=="{}" and execute/insert "\<cr>\<esc>O" when the condition is true, or "\<cr>" otherwise.
Within lh-bracket, I have the following into a C-ftplugin:
call lh#brackets#enrich_imap('<cr>',
\ {'condition': 'getline(".")[col(".")-2:col(".")-1]=="{}"',
\ 'action': 'Cpp_Add2NewLinesBetweenBrackets()'},
\ 1,
\ '\<cr\>'
\ )
function! Cpp_Add2NewLinesBetweenBrackets()
return "\<cr>\<esc>O"
endfunction
I guess (code not tested) it would (*) translate into:
" put it into ftplugin/{yourfiltetype, javascript?}.vim
inoremap <buffer> <silent> <expr> <cr> s:SmartCR()
function s:SmartCR()
return getline(".")[col(".")-2:col(".")-1]=="{}"
\ ? "\<cr>\<esc>O"
\ : "\<cr>"
endfunction
(*) Actually, lh#brackets#enrich_imap does a few other things (the mapping is compatible with LaTeXSuite's IMAP.vim presence ; the mapping can be toggled on/off along with all the other mappings from lh-brackets)

How to process various tasks like video acquisition parallel in Matlab?

I want to acquire image data from stereo camera simultaneously, or in parallel, save somewhere and read the data when need.
Currently I am doing
for i=1:100
start([vid1 vid2]);
imageData1=getdata(vid1,1);
imageData2=getdata(vid2,1);
%do several calculations%
....
end
In this cameras are working serially and it is very slow. How can I make 2 cameras work at a time???
Please help..
P.S : I also tried parfor but it does not help .
Regards
No Parallel Computing Toolbox required!
The following solution can generally solve problems like yours:
First the videos, I just use some vectors as "data" and save them to the workspace, these would be your two video files:
% Creating of some "videos"
fakevideo1 = [1 ; 1 ; 1];
save('fakevideo1','fakevideo1');
fakevideo2 = [2 ; 2 ; 2];
save('fakevideo2','fakevideo2');
The basic trick is to create a function which generates another instance of Matlab:
function [ ] = parallelinstance( fakevideo_number )
% create command
% -sd (set directory), pwd (current directory), -r (run function) ...
% finally "&" to indicate background computation
command = strcat('matlab -sd',{' '},pwd,{' '},'-r "processvideo(',num2str(fakevideo_number),')" -nodesktop -nosplash &');
% call command
system( command{1} );
end
Most important is the use of & at the end of the terminal command!
Within this function another function is called where the actual video processing is done:
function [] = processvideo( fakevideo_number )
% create file and variable name
filename = strcat('fakevideo',num2str(fakevideo_number),'.mat');
varname = strcat('fakevideo',num2str(fakevideo_number));
% load video to workspace or whatever
load(filename);
A = eval(varname);
% do what has to be done
results = A*2;
% save results to workspace, file, grandmothers mailbox, etc.
save([varname 'processed'],'results');
% just to show that both processes run parallel
pause(5)
exit
end
Finally call the two processes in your main script:
% function call with number of video: parallelinstance(fakevideo_number)
parallelinstance(1);
parallelinstance(2);
My code is completely executable, so just play around a bit. I tried to keep it simple.
After all you will find two .mat files with the processed video "data" in your workspace.
Be aware to adjust the string fakevideo to name root of all your video files.