问:
Get id using useParams hook in functional component - react router dom v6
I am following Colt Steele's React course. Sadly, the course is outdated so I chose to migrate to the latest versions of libraries myself.

Coming to the point, I am now facing this error where I am not able to extract URL params using the useParams hook in my functional component. I am pasting my code below for the community to check.

App.js

```<code>import Palette from './Palette';
import seedPalettes from './assets/seedPalettes'
import './css/App.css'
import { generatePalette } from './assets/colorHelpers';
import { Routes, Route, Link, useParams } from 'react-router-dom';

function App() {

  const { id } = useParams()
  const findPalette = id => {
    return seedPalettes.find(function (palette) {
      return palette.id == id;
    })
  }

  console.log(id);

  return (
    <div className='App'>
      <Routes>
        <Route path='/' element={<h1>Welcome Home</h1>} />
        <Route path='/palette/:id' element={<Palette palette={generatePalette(findPalette(id))} />} />
      </Routes>

      {/* <Link to='/palette'>See Palette</Link> */}
      {/* <Palette palette={generatePalette(seedPalettes[4])} /> */}
    </div>
  );
}

export default App;
</code>```

seedPalettes.js

```<code>export default [
    {
        paletteName: "Material UI Colors",
        id: "material-ui-colors",
        emoji: "",
        colors: [
            { name: "red", color: "#F44336" },
            { name: "pink", color: "#E91E63" },
            { name: "purple", color: "#9C27B0" },
            { name: "deeppurple", color: "#673AB7" },
            { name: "indigo", color: "#3F51B5" },
            { name: "blue", color: "#2196F3" },
            { name: "lightblue", color: "#03A9F4" },
            { name: "cyan", color: "#00BCD4" },
            { name: "teal", color: "#009688" },
            { name: "green", color: "#4CAF50" },
            { name: "lightgreen", color: "#8BC34A" },
            { name: "lime", color: "#CDDC39" },
            { name: "yellow", color: "#FFEB3B" },
            { name: "amber", color: "#FFC107" },
            { name: "orange", color: "#FF9800" },
            { name: "deeporange", color: "#FF5722" },
            { name: "brown", color: "#795548" },
            { name: "grey", color: "#9E9E9E" },
            { name: "bluegrey", color: "#607D8B" }
        ]
    },
    {
        paletteName: "Flat UI Colors v1",
        id: "flat-ui-colors-v1",
        emoji: "",
        colors: [
            { name: "Turquoise", color: "#1abc9c" },
            { name: "Emerald", color: "#2ecc71" },
            { name: "PeterRiver", color: "#3498db" },
            { name: "Amethyst", color: "#9b59b6" },
            { name: "WetAsphalt", color: "#34495e" },
            { name: "GreenSea", color: "#16a085" },
            { name: "Nephritis", color: "#27ae60" },
            { name: "BelizeHole", color: "#2980b9" },
            { name: "Wisteria", color: "#8e44ad" },
            { name: "MidnightBlue", color: "#2c3e50" },
            { name: "SunFlower", color: "#f1c40f" },
            { name: "Carrot", color: "#e67e22" },
            { name: "Alizarin", color: "#e74c3c" },
            { name: "Clouds", color: "#ecf0f1" },
            { name: "Concrete", color: "#95a5a6" },
            { name: "Orange", color: "#f39c12" },
            { name: "Pumpkin", color: "#d35400" },
            { name: "Pomegranate", color: "#c0392b" },
            { name: "Silver", color: "#bdc3c7" },
            { name: "Asbestos", color: "#7f8c8d" }
        ]
    },
    {
        paletteName: "Flat UI Colors Dutch",
        id: "flat-ui-colors-dutch",
        emoji: "",
        colors: [
            { name: "Sunflower", color: "#FFC312" },
            { name: "Energos", color: "#C4E538" },
            { name: "BlueMartina", color: "#12CBC4" },
            { name: "LavenderRose", color: "#FDA7DF" },
            { name: "BaraRose", color: "#ED4C67" },
            { name: "RadiantYellow", color: "#F79F1F" },
            { name: "AndroidGreen", color: "#A3CB38" },
            { name: "MediterraneanSea", color: "#1289A7" },
            { name: "LavenderTea", color: "#D980FA" },
            { name: "VerryBerry", color: "#B53471" },
            { name: "PuffinsBill", color: "#EE5A24" },
            { name: "PixelatedGrass", color: "#009432" },
            { name: "MerchantMarineBlue", color: "#0652DD" },
            { name: "ForgottenPurple", color: "#9980FA" },
            { name: "HollyHock", color: "#833471" },
            { name: "RedPigment", color: "#EA2027" },
            { name: "TurkishAqua", color: "#006266" },
            { name: "20000LeaguesUnderTheSea", color: "#1B1464" },
            { name: "CircumorbitalRing", color: "#5758BB" },
            { name: "MagentaPurple", color: "#6F1E51" }
        ]
    },
    {
        paletteName: "Flat UI Colors American",
        id: "flat-ui-colors-american",
        emoji: "",
        colors: [
            { name: "LightGreenishBlue", color: "#55efc4" },
            { name: "FadedPoster", color: "#81ecec" },
            { name: "GreenDarnerTail", color: "#74b9ff" },
            { name: "ShyMoment", color: "#a29bfe" },
            { name: "CityLights", color: "#dfe6e9" },
            { name: "MintLeaf", color: "#00b894" },
            { name: "RobinsEggBlue", color: "#00cec9" },
            { name: "ElectronBlue", color: "#0984e3" },
            { name: "ExodusFruit", color: "#6c5ce7" },
            { name: "SoothingBreeze", color: "#b2bec3" },
            { name: "SourLemon", color: "#ffeaa7" },
            { name: "FirstDate", color: "#fab1a0" },
            { name: "PinkGlamour", color: "#ff7675" },
            { name: "Pico8Pink", color: "#fd79a8" },
            { name: "AmericanRiver", color: "#636e72" },
            { name: "BrightYarrow", color: "#fdcb6e" },
            { name: "OrangeVille", color: "#e17055" },
            { name: "Chi-Gong", color: "#d63031" },
            { name: "PrunusAvium", color: "#e84393" },
            { name: "DraculaOrchid", color: "#2d3436" }
        ]
    },
    {
        paletteName: "Flat UI Colors Aussie",
        id: "flat-ui-colors-aussie",
        emoji: "",
        colors: [
            { name: "Beekeeper", color: "#f6e58d" },
            { name: "SpicedNectarine", color: "#ffbe76" },
            { name: "PinkGlamour", color: "#ff7979" },
            { name: "JuneBud", color: "#badc58" },
            { name: "CoastalBreeze", color: "#dff9fb" },
            { name: "Turbo", color: "#f9ca24" },
            { name: "QuinceJelly", color: "#f0932b" },
            { name: "CarminePink", color: "#eb4d4b" },
            { name: "PureApple", color: "#6ab04c" },
            { name: "HintOfIcePack", color: "#c7ecee" },
            { name: "MiddleBlue", color: "#7ed6df" },
            { name: "Heliotrope", color: "#e056fd" },
            { name: "ExodusFruit", color: "#686de0" },
            { name: "DeepKoamaru", color: "#30336b" },
            { name: "SoaringEagle", color: "#95afc0" },
            { name: "GreenlandGreen", color: "#22a6b3" },
            { name: "SteelPink", color: "#be2edd" },
            { name: "Blurple", color: "#4834d4" },
            { name: "DeepCove", color: "#130f40" },
            { name: "WizardGrey", color: "#535c68" }
        ]
    },
    {
        paletteName: "Flat UI Colors British",
        id: "flat-ui-colors-british",
        emoji: "",
        colors: [
            { name: "ProtossPylon", color: "#00a8ff" },
            { name: "Periwinkle", color: "#9c88ff" },
            { name: "Rise-N-Shine", color: "#fbc531" },
            { name: "DownloadProgress", color: "#4cd137" },
            { name: "Seabrook", color: "#487eb0" },
            { name: "VanaDylBlue", color: "#0097e6" },
            { name: "MattPurple", color: "#8c7ae6" },
            { name: "NanohanachaGold", color: "#e1b12c" },
            { name: "SkirretGreen", color: "#44bd32" },
            { name: "Naval", color: "#40739e" },
            { name: "NasturcianFlower", color: "#e84118" },
            { name: "LynxWhite", color: "#f5f6fa" },
            { name: "BlueberrySoda", color: "#7f8fa6" },
            { name: "MazarineBlue", color: "#273c75" },
            { name: "BlueNights", color: "#353b48" },
            { name: "HarleyOrange", color: "#c23616" },
            { name: "HintOfPensive", color: "#dcdde1" },
            { name: "ChainGangGrey", color: "#718093" },
            { name: "PicoVoid", color: "#192a56" },
            { name: "ElectroMagnetic", color: "#2f3640" }
        ]
    },
    {
        paletteName: "Flat UI Colors Spanish",
        id: "flat-ui-colors-spanish",
        emoji: "",
        colors: [
            { name: "JacksonsPurple", color: "#40407a" },
            { name: "C64Purple", color: "#706fd3" },
            { name: "SwanWhite", color: "#f7f1e3" },
            { name: "SummerSky", color: "#34ace0" },
            { name: "CelestialGreen", color: "#33d9b2" },
            { name: "LuckyPoint", color: "#2c2c54" },
            { name: "Liberty", color: "#474787" },
            { name: "HotStone", color: "#aaa69d" },
            { name: "DevilBlue", color: "#227093" },
            { name: "PalmSpringsSplash", color: "#218c74" },
            { name: "FlourescentRed", color: "#ff5252" },
            { name: "SyntheticPumpkin", color: "#ff793f" },
            { name: "CrocodileTooth", color: "#d1ccc0" },
            { name: "MandarinSorbet", color: "#ffb142" },
            { name: "SpicedButterNut", color: "#ffda79" },
            { name: "EyeOfNewt", color: "#b33939" },
            { name: "ChileanFire", color: "#cd6133" },
            { name: "GreyPorcelain", color: "#84817a" },
            { name: "AlamedaOchre", color: "#cc8e35" },
            { name: "Desert", color: "#ccae62" }
        ]
    },
    {
        paletteName: "Flat UI Colors Indian",
        id: "flat-ui-colors-indian",
        emoji: "",
        colors: [
            { name: "OrchidOrange", color: "#FEA47F" },
            { name: "SpiroDiscoBall", color: "#25CCF7" },
            { name: "HoneyGlow", color: "#EAB543" },
            { name: "SweetGarden", color: "#55E6C1" },
            { name: "FallingStar", color: "#CAD3C8" },
            { name: "RichGardenia", color: "#F97F51" },
            { name: "ClearChill", color: "#1B9CFC" },
            { name: "WhitePepper", color: "#F8EFBA" },
            { name: "Keppel", color: "#58B19F" },
            { name: "ShipsOfficer", color: "#2C3A47" },
            { name: "FieryFuchsia", color: "#B33771" },
            { name: "BlueBell", color: "#3B3B98" },
            { name: "GeorgiaPeach", color: "#FD7272" },
            { name: "OasisStream", color: "#9AECDB" },
            { name: "BrightUbe", color: "#D6A2E8" },
            { name: "MagentaPurple", color: "#6D214F" },
            { name: "EndingNavyBlue", color: "#182C61" },
            { name: "SasquatchSocks", color: "#FC427B" },
            { name: "PineGlade", color: "#BDC581" },
            { name: "HighlighterLavender", color: "#82589F" }
        ]
    },
    {
        paletteName: "Flat UI Colors French",
        id: "flat-ui-colors-french",
        emoji: "",
        colors: [
            { name: "FlatFlesh", color: "#fad390" },
            { name: "MelonMelody", color: "#f8c291" },
            { name: "Livid", color: "#6a89cc" },
            { name: "Spray", color: "#82ccdd" },
            { name: "ParadiseGreen", color: "#b8e994" },
            { name: "SquashBlossom", color: "#f6b93b" },
            { name: "MandarinRed", color: "#e55039" },
            { name: "AzraqBlue", color: "#4a69bd" },
            { name: "Dupain", color: "#60a3bc" },
            { name: "AuroraGreen", color: "#78e08f" },
            { name: "IcelandPoppy", color: "#fa983a" },
            { name: "TomatoRed", color: "#eb2f06" },
            { name: "YueGuangBlue", color: "#1e3799" },
            { name: "GoodSamaritan", color: "#3c6382" },
            { name: "Waterfall", color: "#38ada9" },
            { name: "CarrotOrange", color: "#e58e26" },
            { name: "JalapenoRed", color: "#b71540" },
            { name: "DarkSapphire", color: "#0c2461" },
            { name: "ForestBlues", color: "#0a3d62" },
            { name: "ReefEncounter", color: "#079992" }
        ]
    }
];
</code>```

colorHelpers.js

This is where I am creating my palette from a seed palette.

```<code>import chroma from 'chroma-js';

const levels = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900];

const generatePalette = (starterPalette) => {
    let newPalette = {
        paletteName: starterPalette.paletteName,
        id: starterPalette.id,
        emoji: starterPalette.emoji,
        colors: {}
    };

    for (let level of levels) {
        newPalette.colors[level] = [];
    }

    for (let color of starterPalette.colors) {
        let scale = generateScale(color.color, 10).reverse();
        for (let i in scale) {
            newPalette.colors[levels[i]].push({
                name: `${color.name} ${levels[i]}`,
                id: color.name.toLowerCase().replace(/ /g, '-'),
                hex: scale[i],
                rgb: chroma(scale[i]).css().replace(/,/g, ', '),
                rgba: chroma(scale[i]).css().replace('rgb', 'rgba').replace(')', ',1.0)').replace(/,/g, ', ')
            })
        }
    }

    return newPalette;
}

const getRange = (hexColor) => {
    const end = '#fff';

    return [
        chroma(hexColor).darken(1.4).hex(),
        hexColor,
        end
    ]
}

const generateScale = (hexColor, numOfColors) => {
    return chroma.scale(getRange(hexColor)).mode('lab').colors(numOfColors);
}

export { generatePalette };
</code>```

Please help me, as a beginner, it is very overwhelming :(. Also, sorry for the bulky code blocks.

答:
The useParams hook can only access the route match params of a Route within the context of the Routes component rendering it. App is outside the Routes component that renders a route rendering path='/palette/:id'.

You can create a wrapper component to "sip" the id route match param and do the filtering.

```<code>import seedPalettes from './assets/seedPalettes';

const findPalette = id => seedPalettes.find(palette => palette.id == id);

const PaletteWrapper = () => {
  const { id } = useParams();

  const palette = generatePalette(findPalette(id))

  return <Palette palette={palette} />;
};
</code>```

...

```<code>function App() {
  return (
    <div className='App'>
      <Routes>
        <Route path='/' element={<h1>Welcome Home</h1>} />
        <Route path='/palette/:id' element={<PaletteWrapper />} />
      </Routes>
    </div>
  );
}
</code>```

Body:
I am following Colt Steele's React course. Sadly, the course is outdated so I chose to migrate to the latest versions of libraries myself.

Coming to the point, I am now facing this error where I am not able to extract URL params using the useParams hook in my functional component. I am pasting my code below for the community to check.

App.js

import Palette from './Palette';
import seedPalettes from './assets/seedPalettes'
import './css/App.css'
import { generatePalette } from './assets/colorHelpers';
import { Routes, Route, Link, useParams } from 'react-router-dom';

function App() {

  const { id } = useParams()
  const findPalette = id => {
    return seedPalettes.find(function (palette) {
      return palette.id == id;
    })
  }

  console.log(id);

  return (

      <Routes>
        <Route path='/' element={
Welcome Home
} />
        <Route path='/palette/:id' element={<Palette palette={generatePalette(findPalette(id))} />} />
      </Routes>

      {/* <Link to='/palette'>See Palette</Link> */}
      {/* <Palette palette={generatePalette(seedPalettes[4])} /> */}

  );
}

export default App;

seedPalettes.js

export default [
    {
        paletteName: "Material UI Colors",
        id: "material-ui-colors",
        emoji: "",
        colors: [
            { name: "red", color: "#F44336" },
            { name: "pink", color: "#E91E63" },
            { name: "purple", color: "#9C27B0" },
            { name: "deeppurple", color: "#673AB7" },
            { name: "indigo", color: "#3F51B5" },
            { name: "blue", color: "#2196F3" },
            { name: "lightblue", color: "#03A9F4" },
            { name: "cyan", color: "#00BCD4" },
            { name: "teal", color: "#009688" },
            { name: "green", color: "#4CAF50" },
            { name: "lightgreen", color: "#8BC34A" },
            { name: "lime", color: "#CDDC39" },
            { name: "yellow", color: "#FFEB3B" },
            { name: "amber", color: "#FFC107" },
            { name: "orange", color: "#FF9800" },
            { name: "deeporange", color: "#FF5722" },
            { name: "brown", color: "#795548" },
            { name: "grey", color: "#9E9E9E" },
            { name: "bluegrey", color: "#607D8B" }
        ]
    },
    {
        paletteName: "Flat UI Colors v1",
        id: "flat-ui-colors-v1",
        emoji: "",
        colors: [
            { name: "Turquoise", color: "#1abc9c" },
            { name: "Emerald", color: "#2ecc71" },
            { name: "PeterRiver", color: "#3498db" },
            { name: "Amethyst", color: "#9b59b6" },
            { name: "WetAsphalt", color: "#34495e" },
            { name: "GreenSea", color: "#16a085" },
            { name: "Nephritis", color: "#27ae60" },
            { name: "BelizeHole", color: "#2980b9" },
            { name: "Wisteria", color: "#8e44ad" },
            { name: "MidnightBlue", color: "#2c3e50" },
            { name: "SunFlower", color: "#f1c40f" },
            { name: "Carrot", color: "#e67e22" },
            { name: "Alizarin", color: "#e74c3c" },
            { name: "Clouds", color: "#ecf0f1" },
            { name: "Concrete", color: "#95a5a6" },
            { name: "Orange", color: "#f39c12" },
            { name: "Pumpkin", color: "#d35400" },
            { name: "Pomegranate", color: "#c0392b" },
            { name: "Silver", color: "#bdc3c7" },
            { name: "Asbestos", color: "#7f8c8d" }
        ]
    },
    {
        paletteName: "Flat UI Colors Dutch",
        id: "flat-ui-colors-dutch",
        emoji: "",
        colors: [
            { name: "Sunflower", color: "#FFC312" },
            { name: "Energos", color: "#C4E538" },
            { name: "BlueMartina", color: "#12CBC4" },
            { name: "LavenderRose", color: "#FDA7DF" },
            { name: "BaraRose", color: "#ED4C67" },
            { name: "RadiantYellow", color: "#F79F1F" },
            { name: "AndroidGreen", color: "#A3CB38" },
            { name: "MediterraneanSea", color: "#1289A7" },
            { name: "LavenderTea", color: "#D980FA" },
            { name: "VerryBerry", color: "#B53471" },
            { name: "PuffinsBill", color: "#EE5A24" },
            { name: "PixelatedGrass", color: "#009432" },
            { name: "MerchantMarineBlue", color: "#0652DD" },
            { name: "ForgottenPurple", color: "#9980FA" },
            { name: "HollyHock", color: "#833471" },
            { name: "RedPigment", color: "#EA2027" },
            { name: "TurkishAqua", color: "#006266" },
            { name: "20000LeaguesUnderTheSea", color: "#1B1464" },
            { name: "CircumorbitalRing", color: "#5758BB" },
            { name: "MagentaPurple", color: "#6F1E51" }
        ]
    },
    {
        paletteName: "Flat UI Colors American",
        id: "flat-ui-colors-american",
        emoji: "",
        colors: [
            { name: "LightGreenishBlue", color: "#55efc4" },
            { name: "FadedPoster", color: "#81ecec" },
            { name: "GreenDarnerTail", color: "#74b9ff" },
            { name: "ShyMoment", color: "#a29bfe" },
            { name: "CityLights", color: "#dfe6e9" },
            { name: "MintLeaf", color: "#00b894" },
            { name: "RobinsEggBlue", color: "#00cec9" },
            { name: "ElectronBlue", color: "#0984e3" },
            { name: "ExodusFruit", color: "#6c5ce7" },
            { name: "SoothingBreeze", color: "#b2bec3" },
            { name: "SourLemon", color: "#ffeaa7" },
            { name: "FirstDate", color: "#fab1a0" },
            { name: "PinkGlamour", color: "#ff7675" },
            { name: "Pico8Pink", color: "#fd79a8" },
            { name: "AmericanRiver", color: "#636e72" },
            { name: "BrightYarrow", color: "#fdcb6e" },
            { name: "OrangeVille", color: "#e17055" },
            { name: "Chi-Gong", color: "#d63031" },
            { name: "PrunusAvium", color: "#e84393" },
            { name: "DraculaOrchid", color: "#2d3436" }
        ]
    },
    {
        paletteName: "Flat UI Colors Aussie",
        id: "flat-ui-colors-aussie",
        emoji: "",
        colors: [
            { name: "Beekeeper", color: "#f6e58d" },
            { name: "SpicedNectarine", color: "#ffbe76" },
            { name: "PinkGlamour", color: "#ff7979" },
            { name: "JuneBud", color: "#badc58" },
            { name: "CoastalBreeze", color: "#dff9fb" },
            { name: "Turbo", color: "#f9ca24" },
            { name: "QuinceJelly", color: "#f0932b" },
            { name: "CarminePink", color: "#eb4d4b" },
            { name: "PureApple", color: "#6ab04c" },
            { name: "HintOfIcePack", color: "#c7ecee" },
            { name: "MiddleBlue", color: "#7ed6df" },
            { name: "Heliotrope", color: "#e056fd" },
            { name: "ExodusFruit", color: "#686de0" },
            { name: "DeepKoamaru", color: "#30336b" },
            { name: "SoaringEagle", color: "#95afc0" },
            { name: "GreenlandGreen", color: "#22a6b3" },
            { name: "SteelPink", color: "#be2edd" },
            { name: "Blurple", color: "#4834d4" },
            { name: "DeepCove", color: "#130f40" },
            { name: "WizardGrey", color: "#535c68" }
        ]
    },
    {
        paletteName: "Flat UI Colors British",
        id: "flat-ui-colors-british",
        emoji: "",
        colors: [
            { name: "ProtossPylon", color: "#00a8ff" },
            { name: "Periwinkle", color: "#9c88ff" },
            { name: "Rise-N-Shine", color: "#fbc531" },
            { name: "DownloadProgress", color: "#4cd137" },
            { name: "Seabrook", color: "#487eb0" },
            { name: "VanaDylBlue", color: "#0097e6" },
            { name: "MattPurple", color: "#8c7ae6" },
            { name: "NanohanachaGold", color: "#e1b12c" },
            { name: "SkirretGreen", color: "#44bd32" },
            { name: "Naval", color: "#40739e" },
            { name: "NasturcianFlower", color: "#e84118" },
            { name: "LynxWhite", color: "#f5f6fa" },
            { name: "BlueberrySoda", color: "#7f8fa6" },
            { name: "MazarineBlue", color: "#273c75" },
            { name: "BlueNights", color: "#353b48" },
            { name: "HarleyOrange", color: "#c23616" },
            { name: "HintOfPensive", color: "#dcdde1" },
            { name: "ChainGangGrey", color: "#718093" },
            { name: "PicoVoid", color: "#192a56" },
            { name: "ElectroMagnetic", color: "#2f3640" }
        ]
    },
    {
        paletteName: "Flat UI Colors Spanish",
        id: "flat-ui-colors-spanish",
        emoji: "",
        colors: [
            { name: "JacksonsPurple", color: "#40407a" },
            { name: "C64Purple", color: "#706fd3" },
            { name: "SwanWhite", color: "#f7f1e3" },
            { name: "SummerSky", color: "#34ace0" },
            { name: "CelestialGreen", color: "#33d9b2" },
            { name: "LuckyPoint", color: "#2c2c54" },
            { name: "Liberty", color: "#474787" },
            { name: "HotStone", color: "#aaa69d" },
            { name: "DevilBlue", color: "#227093" },
            { name: "PalmSpringsSplash", color: "#218c74" },
            { name: "FlourescentRed", color: "#ff5252" },
            { name: "SyntheticPumpkin", color: "#ff793f" },
            { name: "CrocodileTooth", color: "#d1ccc0" },
            { name: "MandarinSorbet", color: "#ffb142" },
            { name: "SpicedButterNut", color: "#ffda79" },
            { name: "EyeOfNewt", color: "#b33939" },
            { name: "ChileanFire", color: "#cd6133" },
            { name: "GreyPorcelain", color: "#84817a" },
            { name: "AlamedaOchre", color: "#cc8e35" },
            { name: "Desert", color: "#ccae62" }
        ]
    },
    {
        paletteName: "Flat UI Colors Indian",
        id: "flat-ui-colors-indian",
        emoji: "",
        colors: [
            { name: "OrchidOrange", color: "#FEA47F" },
            { name: "SpiroDiscoBall", color: "#25CCF7" },
            { name: "HoneyGlow", color: "#EAB543" },
            { name: "SweetGarden", color: "#55E6C1" },
            { name: "FallingStar", color: "#CAD3C8" },
            { name: "RichGardenia", color: "#F97F51" },
            { name: "ClearChill", color: "#1B9CFC" },
            { name: "WhitePepper", color: "#F8EFBA" },
            { name: "Keppel", color: "#58B19F" },
            { name: "ShipsOfficer", color: "#2C3A47" },
            { name: "FieryFuchsia", color: "#B33771" },
            { name: "BlueBell", color: "#3B3B98" },
            { name: "GeorgiaPeach", color: "#FD7272" },
            { name: "OasisStream", color: "#9AECDB" },
            { name: "BrightUbe", color: "#D6A2E8" },
            { name: "MagentaPurple", color: "#6D214F" },
            { name: "EndingNavyBlue", color: "#182C61" },
            { name: "SasquatchSocks", color: "#FC427B" },
            { name: "PineGlade", color: "#BDC581" },
            { name: "HighlighterLavender", color: "#82589F" }
        ]
    },
    {
        paletteName: "Flat UI Colors French",
        id: "flat-ui-colors-french",
        emoji: "",
        colors: [
            { name: "FlatFlesh", color: "#fad390" },
            { name: "MelonMelody", color: "#f8c291" },
            { name: "Livid", color: "#6a89cc" },
            { name: "Spray", color: "#82ccdd" },
            { name: "ParadiseGreen", color: "#b8e994" },
            { name: "SquashBlossom", color: "#f6b93b" },
            { name: "MandarinRed", color: "#e55039" },
            { name: "AzraqBlue", color: "#4a69bd" },
            { name: "Dupain", color: "#60a3bc" },
            { name: "AuroraGreen", color: "#78e08f" },
            { name: "IcelandPoppy", color: "#fa983a" },
            { name: "TomatoRed", color: "#eb2f06" },
            { name: "YueGuangBlue", color: "#1e3799" },
            { name: "GoodSamaritan", color: "#3c6382" },
            { name: "Waterfall", color: "#38ada9" },
            { name: "CarrotOrange", color: "#e58e26" },
            { name: "JalapenoRed", color: "#b71540" },
            { name: "DarkSapphire", color: "#0c2461" },
            { name: "ForestBlues", color: "#0a3d62" },
            { name: "ReefEncounter", color: "#079992" }
        ]
    }
];

colorHelpers.js

This is where I am creating my palette from a seed palette.

import chroma from 'chroma-js';

const levels = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900];

const generatePalette = (starterPalette) => {
    let newPalette = {
        paletteName: starterPalette.paletteName,
        id: starterPalette.id,
        emoji: starterPalette.emoji,
        colors: {}
    };

    for (let level of levels) {
        newPalette.colors[level] = [];
    }

    for (let color of starterPalette.colors) {
        let scale = generateScale(color.color, 10).reverse();
        for (let i in scale) {
            newPalette.colors[levels[i]].push({
                name: `${color.name} ${levels[i]}`,
                id: color.name.toLowerCase().replace(/ /g, '-'),
                hex: scale[i],
                rgb: chroma(scale[i]).css().replace(/,/g, ', '),
                rgba: chroma(scale[i]).css().replace('rgb', 'rgba').replace(')', ',1.0)').replace(/,/g, ', ')
            })
        }
    }

    return newPalette;
}

const getRange = (hexColor) => {
    const end = '#fff';

    return [
        chroma(hexColor).darken(1.4).hex(),
        hexColor,
        end
    ]
}

const generateScale = (hexColor, numOfColors) => {
    return chroma.scale(getRange(hexColor)).mode('lab').colors(numOfColors);
}

export { generatePalette };

Please help me, as a beginner, it is very overwhelming :(. Also, sorry for the bulky code blocks.

Body:
The useParams hook can only access the route match params of a Route within the context of the Routes component rendering it. App is outside the Routes component that renders a route rendering path='/palette/:id'.

You can create a wrapper component to "sip" the id route match param and do the filtering.

import seedPalettes from './assets/seedPalettes';

const findPalette = id => seedPalettes.find(palette => palette.id == id);

const PaletteWrapper = () => {
  const { id } = useParams();

  const palette = generatePalette(findPalette(id))

  return <Palette palette={palette} />;
};

...

function App() {
  return (
    <div className='App'>
      <Routes>
        <Route path='/' element={<h1>Welcome Home</h1>} />
        <Route path='/palette/:id' element={<PaletteWrapper />} />
      </Routes>
    </div>
  );
}


来源: stackexchange

问:
How to edit lightning-textarea programatically in Lightning
I'm trying to find a way to modify the value of my lightning-textarea.

Not the variable that holds the value internally.

Things like document.getElementById('textarea').value = 'value'; are not working.

My Textarea:

```<code><lightning-textarea id="textarea" type="text" label="Enter some text" onchange={handleInputChange}></lightning-textarea>
</code>```

Thanks!

答:
In the solution below, clicking the item changes its content. The Element.innerHTML property or the Element.insertAdjacentHTML() method can be used to change the content of the element.

let textarea = document.getElementById("textarea");
let textarea2 = document.getElementById("textarea2");

/* Clicking on the item fires the following event. */
textarea.addEventListener('click', function(event) {
  textarea.innerHTML = "Clicked First Element";
});

/* Clicking on the item fires the following event. */
function clickEvent() {
  try {
    this.textarea2.innerHTML = "Clicked Second Element";
  }
  catch(error) {
    console.log(error);
  }
}```
<pre class="snippet-code-css lang-css prettyprint-override"><code>#textarea, #textarea2 {
  border: 1px solid red;
  padding: 10px;
}</code>```

<lightning-textarea id="textarea" type="text" label="Enter some text">First</lightning-textarea>

<lightning-textarea id="textarea2" type="text" label="Enter some text" onclick="clickEvent()">Second</lightning-textarea>```

ContentLicense: CC BY-SA 4.0

Body:
I'm trying to find a way to modify the value of my lightning-textarea.

Not the variable that holds the value internally.

Things like document.getElementById('textarea').value = 'value'; are not working.

My Textarea:

<lightning-textarea id="textarea" type="text" label="Enter some text" onchange={handleInputChange}></lightning-textarea>

Thanks!

Body:
In the solution below, clicking the item changes its content. The Element.innerHTML property or the Element.insertAdjacentHTML() method can be used to change the content of the element.

let textarea = document.getElementById("textarea");
let textarea2 = document.getElementById("textarea2");

/* Clicking on the item fires the following event. */
textarea.addEventListener('click', function(event) {
  textarea.innerHTML = "Clicked First Element";
});

/* Clicking on the item fires the following event. */
function clickEvent() {
  try {
    this.textarea2.innerHTML = "Clicked Second Element";
  }
  catch(error) {
    console.log(error);
  }
}

#textarea, #textarea2 {
  border: 1px solid red;
  padding: 10px;
}

<!-- First Element -->
<br><lightning-textarea id="textarea" type="text" label="Enter some text">First</lightning-textarea><br><br><br>

<!-- Second Element -->
<lightning-textarea id="textarea2" type="text" label="Enter some text" onclick="clickEvent()">Second</lightning-textarea>


问:
Complex HTML/CSS Layout
I've been a web developer for really quite some time now, but this is something I've never really done, and my progress so far has used some very complex methods.  The following is the layout I want, there are rules to this layout though, as I will explain in a moment.

```<code>    ----------------------------------------------------
    |                      HEADER                      |
    ----------------------------------------------------
     ________   _______________________________________
    |        | |                                       |
    |        | |                                       |
    |        | |                                       |
    |        | |                                       |
    |        | |                                       |
    |        | |                                       |
    |        | |                                       |
    |        | |                                       |
    |________| |                                       |
               |                                       |
               |                                       |
               |                                       |
               |                                       |
               |                                       |
               |_______________________________________|
</code>```

The sidebar and the header are static and so is the body, however you can scroll the body.  Using the CSS property overflow:scroll on a container for the body section is not an option.  The reason being is that it's an ASP.NET application which utilises the maintainpositiononscrollback, meaning that the browser scrollbar - not a contain scrollbar - is what is used to record the x and y position.  I have achieved this but using some complex layout techniques which just aren't pretty.

So my HTML looks like the following:

```<code><div id="header">
  <ul>
    <li><a href="/">Home</a></li>
    <li><a href="#">Telephone</a></li>
    <li><a href="#">My Department</a></li>
    <li><a href="#">My Profile</a></li>
  </ul>
</div>

<div id="sidebar-container">
  <div id="sidebar">
    <!-- sidebar code using ul's and li's -->
  </div>
</div>

<div id="content-top-border"></div>
<div id="content-left-border"></div>

<div id="content-wrap">
  <div id="content">
    <asp:ContentPlaceHolder ID="MainContent" runat="server" />
  </div>
</div>

<div id="content-right-border"></div>
<div id="content-bottom-border"></div>
<div id="bottom-block"></div>
</code>```

So I use all of these divs for a specific reason, so I can absolutely position borders on the content area.  The rest of the divs actually block off content by changing the background colour of them so you can't see the content when you scroll.

My CSS file is far too large to be posting on here, but here's the general idea:

```<code>div#header {
    height:30px;
    background-color:#d7d7d7;
    position:fixed;
    top:0;
    left:0;
    right:0;
}

div#sidebar {
    position:fixed;
    top:30px;
    left:0;
    overflow:auto;
    bottom:4px;
    width:148px;
    background-color:#d7d7d7;
}

div#sidebar ul {
    border:1px solid #9a9a9a;
    border-bottom:0;
    font-family:Tahoma;
    margin:0 0 0 4px;
    padding:0;
    list-style-type:none;
    font-size:0.75em;
    width:137px;
    clear:both;
    background-color:white;
}
</code>```

So as you can see from the sidebar, I set a fixed width, make it position:fixed and then set a background.  The containing
 has a fixed width thus causing a block.  When you horizontally scroll the page, the content will be hidden when it hits the sidebar.  This creates an effect much like any client-side application.

```<code>#content-wrap {
    position: absolute;
    top: 30px;
    bottom: 15px;
    left: 147px;
    right:0;
    background-color:#d7d7d7;
    z-index:-998;
}

#content {
    z-index:-995;
    position:absolute;
    top:0;
    bottom:0;
    right:0;
    left:0;
    padding:10px 10px 20px 10px;
    background-color:#FFF;
    color:#292929;
}
</code>```

So you can see that the #content has absolute positioning keeping it in that content box.  Anything outside of the content box is never displayed even if you scroll horizontally or vertically.

Are there better ways of doing this?  It seems a heck-of-a-lot of HTML/CSS to be doing something really quite simple.

EDIT: This layout isn't a problem whatsoever.  That part isn't even difficult.  What's difficult is maintaining simple HTML/CSS with a complex layout, and by complex, I don't mean something I'm unable to achieve.  I have achieved the desired effect already, I'm just looking for a better way of doing it.

EDIT: This is based on business requirements, I don't have a choice :)

答:
You could use the markup and css here and adapt it slighty to what you need?

Hope this helps

OwnerDisplayName: Kezzer

ContentLicense: CC BY-SA 2.5

Title: Complex HTML/CSS Layout

Body:
I've been a web developer for really quite some time now, but this is something I've never really done, and my progress so far has used some very complex methods.  The following is the layout I want, there are rules to this layout though, as I will explain in a moment.

    ----------------------------------------------------
    |                      HEADER                      |
    ----------------------------------------------------
     ________   _______________________________________
    |        | |                                       |
    |        | |                                       |
    |        | |                                       |
    |        | |                                       |
    |        | |                                       |
    |        | |                                       |
    |        | |                                       |
    |        | |                                       |
    |________| |                                       |
               |                                       |
               |                                       |
               |                                       |
               |                                       |
               |                                       |
               |_______________________________________|

The sidebar and the header are static and so is the body, however you can scroll the body.  Using the CSS property overflow:scroll on a container for the body section is not an option.  The reason being is that it's an ASP.NET application which utilises the maintainpositiononscrollback, meaning that the browser scrollbar - not a contain scrollbar - is what is used to record the x and y position.  I have achieved this but using some complex layout techniques which just aren't pretty.

So my HTML looks like the following:

Home

Telephone

My Department

My Profile

    <asp:ContentPlaceHolder ID="MainContent" runat="server" />

So I use all of these divs for a specific reason, so I can absolutely position borders on the content area.  The rest of the divs actually block off content by changing the background colour of them so you can't see the content when you scroll.

My CSS file is far too large to be posting on here, but here's the general idea:

div#header {
    height:30px;
    background-color:#d7d7d7;
    position:fixed;
    top:0;
    left:0;
    right:0;
}

div#sidebar {
    position:fixed;
    top:30px;
    left:0;
    overflow:auto;
    bottom:4px;
    width:148px;
    background-color:#d7d7d7;
}

div#sidebar ul {
    border:1px solid #9a9a9a;
    border-bottom:0;
    font-family:Tahoma;
    margin:0 0 0 4px;
    padding:0;
    list-style-type:none;
    font-size:0.75em;
    width:137px;
    clear:both;
    background-color:white;
}

So as you can see from the sidebar, I set a fixed width, make it position:fixed and then set a background.  The containing
 has a fixed width thus causing a block.  When you horizontally scroll the page, the content will be hidden when it hits the sidebar.  This creates an effect much like any client-side application.

#content-wrap {
    position: absolute;
    top: 30px;
    bottom: 15px;
    left: 147px;
    right:0;
    background-color:#d7d7d7;
    z-index:-998;
}

#content {
    z-index:-995;
    position:absolute;
    top:0;
    bottom:0;
    right:0;
    left:0;
    padding:10px 10px 20px 10px;
    background-color:#FFF;
    color:#292929;
}

So you can see that the #content has absolute positioning keeping it in that content box.  Anything outside of the content box is never displayed even if you scroll horizontally or vertically.

Are there better ways of doing this?  It seems a heck-of-a-lot of HTML/CSS to be doing something really quite simple.

EDIT: This layout isn't a problem whatsoever.  That part isn't even difficult.  What's difficult is maintaining simple HTML/CSS with a complex layout, and by complex, I don't mean something I'm unable to achieve.  I have achieved the desired effect already, I'm just looking for a better way of doing it.

EDIT: This is based on business requirements, I don't have a choice :)

LastEditorDisplayName: Kezzer


问:
Create PDF with (resized) PNG images using Pycairo - rescaling Surface issue
I have som PNG image links that I want to download, "convert to thumbnails" and save to PDF using Python and Cairo.

Now, I have a working code, but I don't know how to control image size on paper. Is there a way to resize a PyCairo Surface to the dimensions I want (which happens to be smaller than the original)? I want the original pixels to be "shrinked" to a higher resolution (on paper).

Also, I tried Image.rescale() function from PIL, but it gives me back a 20x20 pixel output (out of a 200x200 pixel original image, which is not the banner example on the code). What I want is a 200x200 pixel image plotted inside a 20x20 mm square on paper (instead of a 200x200 mm square as I am getting now)

My current code is:

```<code>#!/usr/bin/python

import cairo, urllib, StringIO, Image   # could I do it without Image module?

paper_width = 210
paper_height = 297
margin = 20

point_to_milimeter = 72/25.4

pdfname = "out.pdf"
pdf = cairo.PDFSurface(pdfname , paper_width*point_to_milimeter, paper_height*point_to_milimeter)
cr = cairo.Context(pdf)
cr.scale(point_to_milimeter, point_to_milimeter)

f=urllib.urlopen("http://cairographics.org/cairo-banner.png")
i=StringIO.StringIO(f.read())
im=Image.open(i)

# are these StringIO operations really necessary?

imagebuffer = StringIO.StringIO()
im.save(imagebuffer, format="PNG")
imagebuffer.seek(0)
imagesurface = cairo.ImageSurface.create_from_png(imagebuffer)

### EDIT: best answer from Jeremy, and an alternate answer from mine:
best_answer = True      # put false to use my own alternate answer
if best_answer:
    cr.save()
    cr.scale(0.5, 0.5)
    cr.set_source_surface(imagesurface, margin, margin)
    cr.paint()
    cr.restore()
else:
    cr.set_source_surface(imagesurface, margin, margin)
    pattern = cr.get_source()
    scalematrix = cairo.Matrix()    # this can also be used to shear, rotate, etc.
    scalematrix.scale(2,2)          # matrix numbers seem to be the opposite - the greater the number, the smaller the source
    scalematrix.translate(-margin,-margin)  # this is necessary, don't ask me why - negative values!!
    pattern.set_matrix(scalematrix)
    cr.paint()

pdf.show_page()
</code>```

Note that the beautiful Cairo banner does not even fit the page...
The ideal result would be that I could control the width and height of this image in user space units (milimeters, in this case), to create a nice header image, for example.

Thanks for reading and for any help or comment!!

答:
Jeremy Flores solved my problem very well by scaling the target surface before setting the imagesurface as source. Even though, perhaps some day you actually NEED to resize a Surface (or transform it in any way), so I will briefly describe the rationale used in my alternate answer (already included in the question), deduced after thoroughly reading the docs:

Set your surface as the context's source - it implicitly creates a cairo.Pattern!!

Use Context.get_source() to get the pattern back;

Create a cairo.Matrix;

Apply this matrix (with all its transforms) to the pattern;

Paint!

The only problem seems to be the transformations working always around the origin, so that scaling and rotation must be preceeded and followed by complementary translations to the origin (bleargh).

ContentLicense: CC BY-SA 3.0

Body:
I have som PNG image links that I want to download, "convert to thumbnails" and save to PDF using Python and Cairo.

Now, I have a working code, but I don't know how to control image size on paper. Is there a way to resize a PyCairo Surface to the dimensions I want (which happens to be smaller than the original)? I want the original pixels to be "shrinked" to a higher resolution (on paper).

Also, I tried Image.rescale() function from PIL, but it gives me back a 20x20 pixel output (out of a 200x200 pixel original image, which is not the banner example on the code). What I want is a 200x200 pixel image plotted inside a 20x20 mm square on paper (instead of a 200x200 mm square as I am getting now)

My current code is:

#!/usr/bin/python

import cairo, urllib, StringIO, Image   # could I do it without Image module?

paper_width = 210
paper_height = 297
margin = 20

point_to_milimeter = 72/25.4

pdfname = "out.pdf"
pdf = cairo.PDFSurface(pdfname , paper_width*point_to_milimeter, paper_height*point_to_milimeter)
cr = cairo.Context(pdf)
cr.scale(point_to_milimeter, point_to_milimeter)

f=urllib.urlopen("http://cairographics.org/cairo-banner.png")
i=StringIO.StringIO(f.read())
im=Image.open(i)

# are these StringIO operations really necessary?

imagebuffer = StringIO.StringIO()
im.save(imagebuffer, format="PNG")
imagebuffer.seek(0)
imagesurface = cairo.ImageSurface.create_from_png(imagebuffer)

### EDIT: best answer from Jeremy, and an alternate answer from mine:
best_answer = True      # put false to use my own alternate answer
if best_answer:
    cr.save()
    cr.scale(0.5, 0.5)
    cr.set_source_surface(imagesurface, margin, margin)
    cr.paint()
    cr.restore()
else:
    cr.set_source_surface(imagesurface, margin, margin)
    pattern = cr.get_source()
    scalematrix = cairo.Matrix()    # this can also be used to shear, rotate, etc.
    scalematrix.scale(2,2)          # matrix numbers seem to be the opposite - the greater the number, the smaller the source
    scalematrix.translate(-margin,-margin)  # this is necessary, don't ask me why - negative values!!
    pattern.set_matrix(scalematrix)
    cr.paint()

pdf.show_page()

Note that the beautiful Cairo banner does not even fit the page...
The ideal result would be that I could control the width and height of this image in user space units (milimeters, in this case), to create a nice header image, for example.

Thanks for reading and for any help or comment!!


问:
Where to free multiple mallocs
I have the following piece of code:

void f(size_t n) {
    int *a = malloc(n * sizeof *a);
    if(a == NULL) {
        report_error_and_exit();
    }

    int *b = malloc(n * sizeof *a);

    if(b == NULL) {
        free(a);
        report_error_and_exit();
    }

    int *c = malloc(n * sizeof *a);
    if(c == NULL) {
        free(a);
        free(b);
        report_error_and_exit();
    }

    /*use a, b, c*/
}
```
<p>or something along those lines. Basically, I need multiple <code>malloc</code>s, and all of them mustn't fail.</p>
<p>I was wondering where should I free <em>some</em> of the allocated memory. As the function gets longer and bigger checking for <code>malloc</code> fails gets more messy.</p>
<p>A possible solution I was thinking was doing something like the following:</p>
<pre class="lang-c prettyprint-override"><code>void f(size_t n) {
    int *a = malloc(n * sizeof *a);
    if(a == NULL) {
        goto malloc_fail;
    }

    /*...*/

malloc_fail:
    free(a);
    free(b);
    /*...*/
    report_error_and_exit();
}
</code>```

however the use of goto is discouraged.

I am wondering what is the appropriate solution to this.

答:
This is actually a classic example of a proper use of goto in C.

While it is possible to abuse goto (and badly), one of the cases where it does make sense is in error handling code such as this.  It only jumps forward, makes the code easier to read, and puts all of the error handling in one place so it's less error prone.

One thing you have to watch however is that if you jump over the initialization of a variable, then that variable is uninitialized.  Given your example, if the first call to malloc which initializes a fails, then your code as currently written will call free on b and c which are not initialized.

This can be fixed by having a different jump destination for each failure and doing the cleanup in the reverse order.

```<code>void f(size_t n) {
    int success = 0;

    int *a = malloc(n * sizeof *a);
    if(a == NULL) {
        goto malloc_fail_a;
    }
    int *b = malloc(n * sizeof *b);
    if(b == NULL) {
        goto malloc_fail_b;
    }
    int *c = malloc(n * sizeof *c);
    if(c == NULL) {
        goto malloc_fail_c;
    }

    /*...*/

    success = 1;

malloc_fail_c:
    free(c);
malloc_fail_b:
    free(b);
malloc_fail_a:
    free(a);
    if (!success) {
        report_error_and_exit();
    }
}
</code>```

Title: Where to free multiple mallocs

Body:
I have the following piece of code:

void f(size_t n) {
    int *a = malloc(n * sizeof *a);
    if(a == NULL) {
        report_error_and_exit();
    }

    int *b = malloc(n * sizeof *a);

    if(b == NULL) {
        free(a);
        report_error_and_exit();
    }

    int *c = malloc(n * sizeof *a);
    if(c == NULL) {
        free(a);
        free(b);
        report_error_and_exit();
    }

    /*use a, b, c*/
}

or something along those lines. Basically, I need multiple mallocs, and all of them mustn't fail.

I was wondering where should I free some of the allocated memory. As the function gets longer and bigger checking for malloc fails gets more messy.

A possible solution I was thinking was doing something like the following:

void f(size_t n) {
    int *a = malloc(n * sizeof *a);
    if(a == NULL) {
        goto malloc_fail;
    }

    /*...*/

malloc_fail:
    free(a);
    free(b);
    /*...*/
    report_error_and_exit();
}

however the use of goto is discouraged.

I am wondering what is the appropriate solution to this.

Body:
This is actually a classic example of a proper use of goto in C.

While it is possible to abuse goto (and badly), one of the cases where it does make sense is in error handling code such as this.  It only jumps forward, makes the code easier to read, and puts all of the error handling in one place so it's less error prone.

One thing you have to watch however is that if you jump over the initialization of a variable, then that variable is uninitialized.  Given your example, if the first call to malloc which initializes a fails, then your code as currently written will call free on b and c which are not initialized.

This can be fixed by having a different jump destination for each failure and doing the cleanup in the reverse order.

void f(size_t n) {
    int success = 0;

    int *a = malloc(n * sizeof *a);
    if(a == NULL) {
        goto malloc_fail_a;
    }
    int *b = malloc(n * sizeof *b);
    if(b == NULL) {
        goto malloc_fail_b;
    }
    int *c = malloc(n * sizeof *c);
    if(c == NULL) {
        goto malloc_fail_c;
    }

    /*...*/

    success = 1;

malloc_fail_c:
    free(c);
malloc_fail_b:
    free(b);
malloc_fail_a:
    free(a);
    if (!success) {
        report_error_and_exit();
    }
}


问:
Redis and channels with Windows
I'm trying to get a var to my consumers.py to send data to the client in real time as a function does API calls and returns that to the browser.

I know channels needs Redis to function, but why? Why can we not just pass a list as it's built to the consumers class or any variable for that matter? From another answer: to store the necessary information required for different instances of consumers to communicate with one another. But what if I only will use one websocket connection, and only one user is allowed to be logged in at a time? This will be locally hosted only and the function is outside of consumers.py that returns the data so subscribing to groups may be where I need these.

Am I missing something or is redis / memurai a must here? I just can't help but to feel there's an easier way.

答:
I ended up using server side events (SSE), specifically django-eventstream, and so far it's worked great as I didn't need the client to interact with the server, for a chat application this would not work.

Eventstream creates an endpoint at /events/ the client can connect to and receive a streaming http response.

Sending data from externalFunc.py:

```<code>send_event('test', 'message', {'text': 'Hello World'})
</code>```

Event listener in HTML page:

```<code>var es = new ReconnectingEventSource('/events/');

es.addEventListener('message', function (e) {
    console.log(e.data);

    var source = new EventSource("/events/")

    var para = document.createElement("P");
    const obj = JSON.parse(event.data)
    para.innerText = obj.text;
    document.body.appendChild(para)

}, false);

es.addEventListener('stream-reset', function (e) {
}, false);
</code>```

Title: Redis and channels with Windows

Body:
I ended up using server side events (SSE), specifically django-eventstream, and so far it's worked great as I didn't need the client to interact with the server, for a chat application this would not work.

Eventstream creates an endpoint at /events/ the client can connect to and receive a streaming http response.

Sending data from externalFunc.py:

send_event('test', 'message', {'text': 'Hello World'})

Event listener in HTML page:

var es = new ReconnectingEventSource('/events/');

es.addEventListener('message', function (e) {
    console.log(e.data);

    var source = new EventSource("/events/")

    var para = document.createElement("P");
    const obj = JSON.parse(event.data)
    para.innerText = obj.text;
    document.body.appendChild(para)

}, false);

es.addEventListener('stream-reset', function (e) {
}, false);


问:
puppeteer page.type() select second element/class
I'm trying to select and edit the first text input of the third div with "nxcard" class

this is the page structure :

```<code><div>
  <div class="nxcard">
    <h3>Lorem ipsum dolor sit amet.</h3>
    <form>
      <input type="number" />
      <input type="text" />
    </form>
  </div>
  <div class="nxcard">
    <h3>Lorem ipsum dolor sit amet.</h3>
    <form>
      <input type="number" />
      <input type="text" />
    </form>
  </div>
  <div class="nxcard">
    <h3>Lorem ipsum dolor sit amet.</h3>
    <form>
      <input type="number" />
      <!-- the input I want to select using pupeteer : -->
      <input type="text" />
    </form>
  </div>
</div>
</code>```

this is the original code (how I'd have done it without puppeteer)

  const loginCard = document.getElementsByClassName("nxCard")[2];
  const loginForm = loginCard.getElementsByTagName("form")[0];
  const loginUserName = loginForm.getElementsByTagName("input")[1];
  loginUserName.value = "user1";
```
<p>and this is how I've tried to do the same thing using puppeteer</p>
```  await page.type(".nxcard[2] form input[1]", "user1");
```

答:
I was able to solve it using the following css selector

await page.type(".nxcard:last-child input:nth-child(1)" , "user1")
```

src : https://www.w3schools.com/cssref/css_selectors.asp

Body:
I'm trying to select and edit the first text input of the third div with "nxcard" class

this is the page structure :

Lorem ipsum dolor sit amet.

    <form>
      <input type="number" />
      <input type="text" />
    </form>

Lorem ipsum dolor sit amet.

    <form>
      <input type="number" />
      <input type="text" />
    </form>

Lorem ipsum dolor sit amet.

    <form>
      <input type="number" />

      <input type="text" />
    </form>

this is the original code (how I'd have done it without puppeteer)

  const loginCard = document.getElementsByClassName("nxCard")[2];
  const loginForm = loginCard.getElementsByTagName("form")[0];
  const loginUserName = loginForm.getElementsByTagName("input")[1];
  loginUserName.value = "user1";

and this is how I've tried to do the same thing using puppeteer

  await page.type(".nxcard[2] form input[1]", "user1");

Body:
I was able to solve it using the following css selector

await page.type(".nxcard:last-child input:nth-child(1)" , "user1")

src : https://www.w3schools.com/cssref/css_selectors.asp


问:
How to get timezone from iso time string in Python?
For instance this:

my_timestamp = '2022-01-02T02:00:02-08:00'

We know that +00:00 is considered UTC, this timestamp -08:00 indicates America/Los_Angeles.

Is there any way to explicitly get that information using any date function in python?

For instance:

```<code>my_timestamp = '2022-01-02T02:00:02-08:00' # iso string
implicit_tz = someFunction(my_timestamp) # return the string "America/Los_Angeles"

</code>```

Is this possible? Thanks!

答:
As per the comments above, this code will output all the possible timezones for your ISO string.
Is up to you which one to choose.</p>
```<code>from dateutil.parser import isoparse
import dateutil.tz as dtz
import pytz
my_timestamp = '2022-01-02T02:00:02-08:00' # iso string
my_timestamp_parsed = isoparse(my_timestamp)
my_timezone = isoparse(my_timestamp).tzinfo
for name in pytz.common_timezones:
    timezone=dtz.gettz(name)
    try:
        if timezone.utcoffset(my_timestamp_parsed) == my_timezone.utcoffset(my_timestamp_parsed):
            print(name)
    except AttributeError:
        pass
</code>```

Body:
For instance this:

my_timestamp = '2022-01-02T02:00:02-08:00'

We know that +00:00 is considered UTC, this timestamp -08:00 indicates America/Los_Angeles.

Is there any way to explicitly get that information using any date function in python?

For instance:

my_timestamp = '2022-01-02T02:00:02-08:00' # iso string
implicit_tz = someFunction(my_timestamp) # return the string "America/Los_Angeles"

Is this possible? Thanks!

Body:
As per the comments above, this code will output all the possible timezones for your ISO string.
Is up to you which one to choose.

from dateutil.parser import isoparse
import dateutil.tz as dtz
import pytz
my_timestamp = '2022-01-02T02:00:02-08:00' # iso string
my_timestamp_parsed = isoparse(my_timestamp)
my_timezone = isoparse(my_timestamp).tzinfo
for name in pytz.common_timezones:
    timezone=dtz.gettz(name)
    try:
        if timezone.utcoffset(my_timestamp_parsed) == my_timezone.utcoffset(my_timestamp_parsed):
            print(name)
    except AttributeError:
        pass


问:
Write csv with different separators in same df in R
I have a dataframe in R and I need to export it as .csv with "," separator to the column names and ";" separator to the rest of the dataframe (all the data rows).

So I need something like this:

```<code>name_col1,name_col2,name_col3
v1;v2;v3
v4;v5;v6
</code>```

答:
With readr you can use write_delim() to output a file with comma-separated column names then call it a second time, without column names, and in append mode.

library(read)

mtcars[0, ] %>%
  write_delim(file = "test.dat",delim = ',', col_names = TRUE)

mtcars %>%
  write_delim(file = "test.dat",delim = ';', col_names = FALSE, append = TRUE)
```

Body:
I have a dataframe in R and I need to export it as .csv with "," separator to the column names and ";" separator to the rest of the dataframe (all the data rows).

So I need something like this:

name_col1,name_col2,name_col3
v1;v2;v3
v4;v5;v6


问:
How do I get my settings from PyCharm in a file so not to lose them when updating PyCharm or creating a new Project?
It's happened to me that either I update pycharm (and need to completely reinstall it e.g. M1 mac chip update) or I am about to create a new project that is going to share my folders (but not all) with my previous projects. It usually leads me spending a bunch of time re setting pycharm up e.g. resetting passwords, paths to folders for deployment (when pushing to remote on save), etc. This is time consuming and really annoying. Is there some type of pycharnm.config file I save somewhere external to pycharm so to not lose it if I uninstall it or copy paste it to the new project to not redo the work?

How do I get my custom settings (especially from deployment stuff) in a modular way in PyCharm?

related:

https://intellij-support.jetbrains.com/hc/en-us/community/posts/115000081744-How-to-save-deployment-configuration-

related in part with respect to the deployment: PhpStorm: How to export deployment settings from a project to another one?

perhaps is in the .idea folder but none of the folders under my project have it! What is the .idea folder?

答:
To save the settings do

```<code>File | Manage IDE Settings | Export Settings
</code>```

I did not need to import them since I opened the new pycharm and it already new everything.

For the deployment settings save the.idea folder of the project (which was at the root of the folder with the folder name of the github repo that created the project, if you can't find the .idea folder see Show .idea folder in PhpStorm project tool window). Save it somewhere then put it in the .idea of the project folder and it should be ready.

For details on m1 chip upgrade see: https://stackoverflow.com/a/71025787/1601580 but just installing the dmg works and it seems you don't have to do any of the above I said for some strange reason even if you uninstall the prev pycharm version.

if you get issue with xcode and git see this: https://apple.stackexchange.com/a/436612/72191 and https://stackoverflow.com/a/71026739/1601580

e.g. getting error:

```<code>xcrun: error: unable to load libxcrun (dlopen(/Library/Developer/CommandLineTools/usr/lib/libxcrun.dylib, 0x0005): tried: '/Library/Developer/CommandLineTools/usr/lib/libxcrun.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e')), '/usr/lib/libxcrun.dylib' (no such file)).
</code>```

Body:
To save the settings do

File | Manage IDE Settings | Export Settings

I did not need to import them since I opened the new pycharm and it already new everything.

For the deployment settings save the.idea folder of the project (which was at the root of the folder with the folder name of the github repo that created the project, if you can't find the .idea folder see Show .idea folder in PhpStorm project tool window). Save it somewhere then put it in the .idea of the project folder and it should be ready.

For details on m1 chip upgrade see: https://stackoverflow.com/a/71025787/1601580 but just installing the dmg works and it seems you don't have to do any of the above I said for some strange reason even if you uninstall the prev pycharm version.

if you get issue with xcode and git see this: https://apple.stackexchange.com/a/436612/72191 and https://stackoverflow.com/a/71026739/1601580

e.g. getting error:

xcrun: error: unable to load libxcrun (dlopen(/Library/Developer/CommandLineTools/usr/lib/libxcrun.dylib, 0x0005): tried: '/Library/Developer/CommandLineTools/usr/lib/libxcrun.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e')), '/usr/lib/libxcrun.dylib' (no such file)).


问:
Why HTMLElement passed to the component from html via event handler points to the wrong html element?
I have a table and I want to pass HTMLElement of the table cell to the component via click event hadler. At the very begininng I have the pointer to the correct table cell but after I init change detection manually the pointer points to the wrong cell (the next to the correct one)

I can't find out why it happens. I created example with console.log(tableCell) before and after initialization of the change detection (method setEditMode in AppComponent)

https://stackblitz.com/edit/angular-module-sandbox-btszav?file=src/app/app.component.html

app.component.html

    <button (click)="showClipboardText()">Fill the table</button>

            {{ colName }}

            {{ cellData?.value }}
            <input
              type="text"
              (keydown)="saveEdit($event, rowIndex, colIndex)"
              (blur)="saveEdit($event, rowIndex, colIndex)"
              *ngIf="!!data[rowIndex][colIndex]?.isEditMode"
            />

          <button (click)="addRow()">+</button>

```
<p><strong>app.component.ts</strong></p>
<pre class="lang-js prettyprint-override"><code>    import {
          ChangeDetectorRef,
          Component,
          ElementRef,
          QueryList,
          ViewChildren,
        } from '@angular/core';

        @Component({
          selector: 'my-app',
          templateUrl: './app.component.html',
          styleUrls: ['./app.component.css'],
        })
        export class AppComponent {
          @ViewChildren('tableCell', { read: ElementRef })
          tableCells: QueryList<ElementRef>;

          colNames = ['Client', 'Order', 'Total'];

          data: Array<Array<{ isEditMode?: boolean; value?: string }>> = [
            Array(this.colNames.length),
          ];

          activeCell: { row: number; col: number };

          constructor(private cd: ChangeDetectorRef) {}

          addRow(): void {
            this.data.push(Array(this.colNames.length));
          }

          setEditMode(row: number, col: number, tableCell: HTMLElement): void {
            console.log(tableCell.dataset['colName']);

            if (this.activeCell) {
              const previousCellData =
                this.data[this.activeCell.row][this.activeCell.col];
              previousCellData.isEditMode = false;
            }
            if (!!this.data[row][col]) {
              this.data[row][col].isEditMode = true;
              this.data[row][col].value = '';
            } else {
              this.data[row][col] = { ...this.data[row][col], isEditMode: true };
            }
            this.activeCell = { row, col };
            this.cd.detectChanges();
            console.log(tableCell.dataset['colName']);
          }

          saveEdit(event: Event, row: number, col: number): void {
            if ((<KeyboardEvent>event).key && (<KeyboardEvent>event).key !== 'Enter')
              return;

            const value = (<HTMLInputElement>event.target).value;
            const previousCellData =
              this.data[this.activeCell.row][this.activeCell.col];
            previousCellData.isEditMode = false;

            this.data[row][col].value = value;
          }
        }
</code>```

答:
Working stackblitz: https://stackblitz.com/edit/angular-module-sandbox-cdbpbq?file=src/app/app.component.ts

Your issue boils down to the fact that we go from having an array of size 3, but with no default values defined. photo:

Thus, each time we defined a value, the colIndex increased by one. You can check this if you set a data attribute for the colIndex as you did for the colName. The solution involves defining a default value for your row.

```<code>data: Array<Array<{ isEditMode?: boolean; value?: string }>> = [
    [
      {
        isEditMode: false,
        value: '',
      },
      {
        isEditMode: false,
        value: '',
      },
      {
        isEditMode: false,
        value: '',
      },
    ],
  ];
</code>```

However, this also means we need to update our add row method to look like so:

```<code>addRow(): void {
    this.data.push([
      {
        isEditMode: false,
        value: '',
      },
      {
        isEditMode: false,
        value: '',
      },
      {
        isEditMode: false,
        value: '',
      },
    ]);
  }
</code>```

Previously all you did was just add an array of length three, but with no cells defined within it.

Body:
I have a table and I want to pass HTMLElement of the table cell to the component via click event hadler. At the very begininng I have the pointer to the correct table cell but after I init change detection manually the pointer points to the wrong cell (the next to the correct one)

I can't find out why it happens. I created example with console.log(tableCell) before and after initialization of the change detection (method setEditMode in AppComponent)

https://stackblitz.com/edit/angular-module-sandbox-btszav?file=src/app/app.component.html

app.component.html

    <button (click)="showClipboardText()">Fill the table</button>

            {{ colName }}

            {{ cellData?.value }}
            <input
              type="text"
              (keydown)="saveEdit($event, rowIndex, colIndex)"
              (blur)="saveEdit($event, rowIndex, colIndex)"
              *ngIf="!!data[rowIndex][colIndex]?.isEditMode"
            />

          <button (click)="addRow()">+</button>

app.component.ts

    import {
          ChangeDetectorRef,
          Component,
          ElementRef,
          QueryList,
          ViewChildren,
        } from '@angular/core';

        @Component({
          selector: 'my-app',
          templateUrl: './app.component.html',
          styleUrls: ['./app.component.css'],
        })
        export class AppComponent {
          @ViewChildren('tableCell', { read: ElementRef })
          tableCells: QueryList<ElementRef>;

          colNames = ['Client', 'Order', 'Total'];

          data: Array<Array<{ isEditMode?: boolean; value?: string }>> = [
            Array(this.colNames.length),
          ];

          activeCell: { row: number; col: number };

          constructor(private cd: ChangeDetectorRef) {}

          addRow(): void {
            this.data.push(Array(this.colNames.length));
          }

          setEditMode(row: number, col: number, tableCell: HTMLElement): void {
            console.log(tableCell.dataset['colName']);

            if (this.activeCell) {
              const previousCellData =
                this.data[this.activeCell.row][this.activeCell.col];
              previousCellData.isEditMode = false;
            }
            if (!!this.data[row][col]) {
              this.data[row][col].isEditMode = true;
              this.data[row][col].value = '';
            } else {
              this.data[row][col] = { ...this.data[row][col], isEditMode: true };
            }
            this.activeCell = { row, col };
            this.cd.detectChanges();
            console.log(tableCell.dataset['colName']);
          }

          saveEdit(event: Event, row: number, col: number): void {
            if ((<KeyboardEvent>event).key && (<KeyboardEvent>event).key !== 'Enter')
              return;

            const value = (<HTMLInputElement>event.target).value;
            const previousCellData =
              this.data[this.activeCell.row][this.activeCell.col];
            previousCellData.isEditMode = false;

            this.data[row][col].value = value;
          }
        }

Body:
Working stackblitz: https://stackblitz.com/edit/angular-module-sandbox-cdbpbq?file=src/app/app.component.ts

Your issue boils down to the fact that we go from having an array of size 3, but with no default values defined. photo:

Thus, each time we defined a value, the colIndex increased by one. You can check this if you set a data attribute for the colIndex as you did for the colName. The solution involves defining a default value for your row.

data: Array<Array<{ isEditMode?: boolean; value?: string }>> = [
    [
      {
        isEditMode: false,
        value: '',
      },
      {
        isEditMode: false,
        value: '',
      },
      {
        isEditMode: false,
        value: '',
      },
    ],
  ];

However, this also means we need to update our add row method to look like so:

addRow(): void {
    this.data.push([
      {
        isEditMode: false,
        value: '',
      },
      {
        isEditMode: false,
        value: '',
      },
      {
        isEditMode: false,
        value: '',
      },
    ]);
  }

Previously all you did was just add an array of length three, but with no cells defined within it.


问:
R survival package survfit function doesn't use conf.int if conf.int != 0.95 and type = 'interval' or 'interval2'
I can't get survfit to calculate anything other the 95% confidence limits when type='interval' or type='interval2'.  I also can't seem to find any bug reports on this issue.  Am I using the conf.int argument correctly?  I can calculate quantiles with quantile(fit), but would like to be able to use plot(fit) to plot an 80% confidence interval.</p>

```<code>> library(survival)
> tdata <- data.frame(time  =c(1,1,1,2,2,2,3,3,3,4,4,4),
+                     status=rep(c(1,0,2),4))
> fit  <- survfit(Surv(time, time, status, type='interval') ~1,
+               data=tdata, conf.int=0.80)
> fit
Call: survfit(formula = Surv(time, time, status, type = "interval") ~
    1, data = tdata, conf.int = 0.8)

records   n.max n.start  events  median 0.95LCL 0.95UCL
     12      12      12       8       3       2      NA
> plot(fit) # plots 95% confidence intervals
> sessionInfo()
R version 3.0.1 (2013-05-16)
Platform: x86_64-w64-mingw32/x64 (64-bit)

locale:
[1] LC_COLLATE=English_United States.1252
[2] LC_CTYPE=English_United States.1252
[3] LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C
[5] LC_TIME=English_United States.1252

attached base packages:
[1] splines   stats     graphics  grDevices utils     datasets  methods
[8] base

other attached packages:
[1] survival_2.37-7
</code>```

答:
Agreed that type = "interval" requires values for "time" and "time2" whenever status = 3.
Nonetheless, the original observation and question is valid.  When type = "interval" the survfit function does not respond to the argument conf.int.  It returns 95% confidence intervals even when supplied with conf.int = 0.80 ?

Here is example code

```<code>tdata <- data.frame(time  =c(1,0,1,0,2,0,3,0,3,1,4,2),
                           time2  =c(1,1,1,2,2,2,3,3,3,4,4,4),
                           status =c(0,3,0,3,0,3,0,3,0,3,0,3))
fit  <- survfit(Surv(time, time2, status, type='interval') ~1,
                           data=tdata, conf.int=0.80)    # requests to calculate 80% confidence intervals
fit             # returns 95% confidence interval
plot(fit)       # plots 95% confidence intervals
</code>```

sessionInfo()

```<code>R version 4.0.2 (2020-06-22)
Platform: i386-w64-mingw32/i386 (32-bit)
Running under: Windows 10 x64 (build 14393)

Matrix products: default

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

other attached packages:
[1] survminer_0.4.9 ggpubr_0.4.0    ggplot2_3.3.5   survival_3.1-12
</code>```

Body:
I can't get survfit to calculate anything other the 95% confidence limits when type='interval' or type='interval2'.  I also can't seem to find any bug reports on this issue.  Am I using the conf.int argument correctly?  I can calculate quantiles with quantile(fit), but would like to be able to use plot(fit) to plot an 80% confidence interval.

> library(survival)
> tdata <- data.frame(time  =c(1,1,1,2,2,2,3,3,3,4,4,4),
+                     status=rep(c(1,0,2),4))
> fit  <- survfit(Surv(time, time, status, type='interval') ~1,
+               data=tdata, conf.int=0.80)
> fit
Call: survfit(formula = Surv(time, time, status, type = "interval") ~
    1, data = tdata, conf.int = 0.8)

records   n.max n.start  events  median 0.95LCL 0.95UCL
     12      12      12       8       3       2      NA
> plot(fit) # plots 95% confidence intervals
> sessionInfo()
R version 3.0.1 (2013-05-16)
Platform: x86_64-w64-mingw32/x64 (64-bit)

locale:
[1] LC_COLLATE=English_United States.1252
[2] LC_CTYPE=English_United States.1252
[3] LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C
[5] LC_TIME=English_United States.1252

attached base packages:
[1] splines   stats     graphics  grDevices utils     datasets  methods
[8] base

other attached packages:
[1] survival_2.37-7

Body:
Agreed that type = "interval" requires values for "time" and "time2" whenever status = 3.
Nonetheless, the original observation and question is valid.  When type = "interval" the survfit function does not respond to the argument conf.int.  It returns 95% confidence intervals even when supplied with conf.int = 0.80 ?

Here is example code

tdata <- data.frame(time  =c(1,0,1,0,2,0,3,0,3,1,4,2),
                           time2  =c(1,1,1,2,2,2,3,3,3,4,4,4),
                           status =c(0,3,0,3,0,3,0,3,0,3,0,3))
fit  <- survfit(Surv(time, time2, status, type='interval') ~1,
                           data=tdata, conf.int=0.80)    # requests to calculate 80% confidence intervals
fit             # returns 95% confidence interval
plot(fit)       # plots 95% confidence intervals

sessionInfo()

R version 4.0.2 (2020-06-22)
Platform: i386-w64-mingw32/i386 (32-bit)
Running under: Windows 10 x64 (build 14393)

Matrix products: default

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

other attached packages:
[1] survminer_0.4.9 ggpubr_0.4.0    ggplot2_3.3.5   survival_3.1-12


问:
Where are return values stored and how/can they be incremented?
I've done my fair share of reading and researching but I still don't 100% get it.
For this solution of " Minimum Depth of Binary Tree", the idea of having multiple returns in a recursive function is killing me. I'm not exactly sure how the value for the "minimum depth" is being incremented, and I understand it may have something to do with my misunderstanding of return statements work. Please help, thank you.</p>
```<code>int minDepth(Node *root) {
        if(!root) return 0;

        if(!root->left) return 1 + minDepth(root->right);

        if(!root->right) return 1 + minDepth(root->left);

        return 1+min(minDepth(root->left),minDepth(root->right));
    }
</code>```

答:
If it helps, logically, what you have above could just as well have been written</p>
```<code>int minDepth(Node *root) {

    int result;

    if(!root)
        result = 0;
    else if(!root->left)
        result = 1 + minDepth(root->right);
    else if(!root->right)
        result = 1 + minDepth(root->left);
    else
        result = 1 + min(minDepth(root->left), minDepth(root->right));

    return result;
}
</code>```

Body:
I've done my fair share of reading and researching but I still don't 100% get it.
For this solution of " Minimum Depth of Binary Tree", the idea of having multiple returns in a recursive function is killing me. I'm not exactly sure how the value for the "minimum depth" is being incremented, and I understand it may have something to do with my misunderstanding of return statements work. Please help, thank you.

int minDepth(Node *root) {
        if(!root) return 0;

        if(!root->left) return 1 + minDepth(root->right);

        if(!root->right) return 1 + minDepth(root->left);

        return 1+min(minDepth(root->left),minDepth(root->right));
    }

Body:
If it helps, logically, what you have above could just as well have been written

int minDepth(Node *root) {

    int result;

    if(!root)
        result = 0;
    else if(!root->left)
        result = 1 + minDepth(root->right);
    else if(!root->right)
        result = 1 + minDepth(root->left);
    else
        result = 1 + min(minDepth(root->left), minDepth(root->right));

    return result;
}


问:
Google Model Viewer Hide AR preview button when browser not support AR
I'm using google model viewer lib. for AR support for an e-commerce site.

Custom button View in you space

I want to hide AR preview button(View in your space) for those browsers who don't have capability of AR. and I also want to show custom "Add to cart" button which support "android" and "ios"?

Add to cart button in AR

I add the code like the below ex. it's showing in android but not in ios

```<code><model-viewer>
    <button>Add to cart</button>
</model-viewer>
</code>```

答:
To have the button apear in iOS you will have to add a usdz model using the ios-src parameter.

```<code>ios-src="/models/Astronaut.usdz"
</code>```

You can also add quick-look to the ar-modes and have modelViewer try to auto generate a usdz model on the fly.

ar-modes Docs

Body:
I'm using google model viewer lib. for AR support for an e-commerce site.

Custom button View in you space

I want to hide AR preview button(View in your space) for those browsers who don't have capability of AR. and I also want to show custom "Add to cart" button which support "android" and "ios"?

Add to cart button in AR

I add the code like the below ex. it's showing in android but not in ios

<model-viewer>
    <button>Add to cart</button>
</model-viewer>

Body:
To have the button apear in iOS you will have to add a usdz model using the ios-src parameter.

ios-src="/models/Astronaut.usdz"

You can also add quick-look to the ar-modes and have modelViewer try to auto generate a usdz model on the fly.

ar-modes Docs


问:
python fuzzywuzzy's process.extract(): how does it work?
I am trying to understand how the python module fuzzywuzzy's function process.extract() work?

I mainly read about the fuzzywuzzy package here: http://chairnerd.seatgeek.com/fuzzywuzzy-fuzzy-string-matching-in-python/, which is a great post explanining different scenarios when trying to do fuzzy matching. They discussed several scenarios for Partial String Similarity:

1) Out Of Order

  2) Token Sort

  3) Token Set

And then, from this post: https://pathindependence.wordpress.com/2015/10/31/tutorial-fuzzywuzzy-string-matching-in-python-improving-merge-accuracy-across-data-products-and-naming-conventions/ I learned how to use fuzzywuzzy's process.extract() function to basically select the top k matches.

I cannot find too much info regarding how the process.extract() function works. Here's the definition/information I found on their GitHub page (https://github.com/seatgeek/fuzzywuzzy/blob/master/fuzzywuzzy/process.py), that this function:

Find best matches in a list or dictionary of choices, return a
      list of tuples containing the match and it's score. If a dictionary
      is used, also returns the key for each match.

However, it does not provide details regarding HOW it's finding the best? Did it take all the 3 scenarios I've mentioned above to find this?

The reason why I ask, is because, when I used this function, sometimes there are two strings that are very similar but are not matched.

for example in my current sample data set, for the to-be-match-string

"Total replenishment lead time (in workdays)"

it is matched to

"PLANNING_TIME_FENCE_CODE", "BUILD_IN_WIP_FLAG"

but not to (the right answer)

"FULL_LEAD_TIME"

Even though the right answer has "lead time" just like the to-be-match-string does, it is not matched to the to-be-match-string at all. WHY? and somehow, the other ones that do not look like the to-be-match-string get to be matched. WHY? I am quite clueless now.

答:
I've been asking myself the same question about the process.extract default scorer WRatio -> for some reason the result is really weird, all the other scorer identify the correct match, ie Alphabet, but probably due to a lonely A character in my query string I get a higher match for A/S substrings than Alphabet -> Alphabet with the default parser, if anyone can shed some light on why this is, that'd be awesome:

```<code>process.extract("ALPHABET- A",RIFT_IDS['EntityName'], scorer = fuzz.token_set_ratio, limit=3)
[('Alphabet Inc', 89, 4955), ('Haemato AG', 60, 9078), ('Vale SA', 59, 1894)]

process.extract("ALPHABET- A",RIFT_IDS['EntityName'], scorer = fuzz.token_sort_ratio, limit=3)
[('Alphabet Inc', 73, 4955), ('Haemato AG', 60, 9078), ('Vale SA', 59, 1894)]

process.extract("ALPHABET- A",RIFT_IDS['EntityName'], scorer = fuzz.partial_ratio, limit=3)
[('Alphabet Inc', 82, 4955), ('EQT AB', 73, 5838), ('BEL SA', 67, 2430)]

process.extract("ALPHABET- A",RIFT_IDS['EntityName'], scorer = fuzz.ratio, limit=3)
[('Alphabet Inc', 78, 4955), ('Alpha Bank SA', 67, 4720), ('Pharnext SA', 64, 9228)]

process.extract("ALPHABET- A",RIFT_IDS['EntityName'], limit=3)
[('Iss A/S', 86, 4), ('Vestas Wind Systems A/S', 86, 87), ('AP Moeller - Maersk A/S', 86, 126)]
</code>```

EDIT: Well from the github code there appear to be another scorer called partial_token_set_ratio which appears to be the culprit, still I'd like to understand which scorer are used in Wration and what their respective weights are. It'd be great if it were possible to create our own custom WRatio & chose which scorers it uses.

Body:
I've been asking myself the same question about the process.extract default scorer WRatio -> for some reason the result is really weird, all the other scorer identify the correct match, ie Alphabet, but probably due to a lonely A character in my query string I get a higher match for A/S substrings than Alphabet -> Alphabet with the default parser, if anyone can shed some light on why this is, that'd be awesome:

process.extract("ALPHABET- A",RIFT_IDS['EntityName'], scorer = fuzz.token_set_ratio, limit=3)
[('Alphabet Inc', 89, 4955), ('Haemato AG', 60, 9078), ('Vale SA', 59, 1894)]

process.extract("ALPHABET- A",RIFT_IDS['EntityName'], scorer = fuzz.token_sort_ratio, limit=3)
[('Alphabet Inc', 73, 4955), ('Haemato AG', 60, 9078), ('Vale SA', 59, 1894)]

process.extract("ALPHABET- A",RIFT_IDS['EntityName'], scorer = fuzz.partial_ratio, limit=3)
[('Alphabet Inc', 82, 4955), ('EQT AB', 73, 5838), ('BEL SA', 67, 2430)]

process.extract("ALPHABET- A",RIFT_IDS['EntityName'], scorer = fuzz.ratio, limit=3)
[('Alphabet Inc', 78, 4955), ('Alpha Bank SA', 67, 4720), ('Pharnext SA', 64, 9228)]

process.extract("ALPHABET- A",RIFT_IDS['EntityName'], limit=3)
[('Iss A/S', 86, 4), ('Vestas Wind Systems A/S', 86, 87), ('AP Moeller - Maersk A/S', 86, 126)]

EDIT: Well from the github code there appear to be another scorer called partial_token_set_ratio which appears to be the culprit, still I'd like to understand which scorer are used in Wration and what their respective weights are. It'd be great if it were possible to create our own custom WRatio & chose which scorers it uses.


问:
Start long running background process and check the status
I want to start a potentially long running background process from Delphi. I want to leave the process running independently, but first I want to check that the process started OK.

If anything went wrong on startup, I want to capture any output written to standardErr and log it. If the background process starts OK, my program needs to be able to exit and leave the spawned process running.

The psuedo code would be something like this:

```<code>process:=RunProgramInBackground('someCommand.exe');
sleep(1000); // Wait a bit to see if the program started OK
if process.Finished and process.ExitCode=FAIL then
    Raise Exception.Create(process.ErrorStream);
process.Dispose; // Close any connection we may still have to the running process
Program.Exit; // Background process keeps running
</code>```

I've looked at a few things (WinExec, CreateProcess, ShellExecute, JclMiscel) but can't find any examples for what I'm trying to do. What is the best way to do this?

I'm using Delphi 2010

The background process is a 3rd party program I don't have the source to.

答:
Check out this article. I quote: "Here is an updated and improved version of the code that allows you to choose in code whether the calling application waits until the other program closes before continuing or just carries on leaving the newly started program to its own devices".

```<code>procedure ExecNewProcess(ProgramName : String; Wait: Boolean);
var
 StartInfo : TStartupInfo;
 ProcInfo : TProcessInformation;
 CreateOK : Boolean;

begin
 { fill with known state }
 FillChar(StartInfo,SizeOf(TStartupInfo),#0);
 FillChar(ProcInfo,SizeOf(TProcessInformation),#0);
 StartInfo.cb := SizeOf(TStartupInfo);
 CreateOK := CreateProcess(nil, PChar(ProgramName), nil, nil,False,
                    CREATE_NEW_PROCESS_GROUP+NORMAL_PRIORITY_CLASS,
                    nil, nil, StartInfo, ProcInfo);
 { check to see if successful }
 if CreateOK then
  begin
    //may or may not be needed. Usually wait for child processes
   if Wait then
    WaitForSingleObject(ProcInfo.hProcess, INFINITE);
  end
 else
  begin
   ShowMessage('Unable to run '+ProgramName);
  end;

 CloseHandle(ProcInfo.hProcess);
 CloseHandle(ProcInfo.hThread);
end;
</code>```

Edited: after reading your comments, I suggest that you look at this previous question

Body:
I want to start a potentially long running background process from Delphi. I want to leave the process running independently, but first I want to check that the process started OK.

If anything went wrong on startup, I want to capture any output written to standardErr and log it. If the background process starts OK, my program needs to be able to exit and leave the spawned process running.

The psuedo code would be something like this:

process:=RunProgramInBackground('someCommand.exe');
sleep(1000); // Wait a bit to see if the program started OK
if process.Finished and process.ExitCode=FAIL then
    Raise Exception.Create(process.ErrorStream);
process.Dispose; // Close any connection we may still have to the running process
Program.Exit; // Background process keeps running

I've looked at a few things (WinExec, CreateProcess, ShellExecute, JclMiscel) but can't find any examples for what I'm trying to do. What is the best way to do this?

I'm using Delphi 2010

The background process is a 3rd party program I don't have the source to.

Body:
Check out this article. I quote: "Here is an updated and improved version of the code that allows you to choose in code whether the calling application waits until the other program closes before continuing or just carries on leaving the newly started program to its own devices".

procedure ExecNewProcess(ProgramName : String; Wait: Boolean);
var
 StartInfo : TStartupInfo;
 ProcInfo : TProcessInformation;
 CreateOK : Boolean;

begin
 { fill with known state }
 FillChar(StartInfo,SizeOf(TStartupInfo),#0);
 FillChar(ProcInfo,SizeOf(TProcessInformation),#0);
 StartInfo.cb := SizeOf(TStartupInfo);
 CreateOK := CreateProcess(nil, PChar(ProgramName), nil, nil,False,
                    CREATE_NEW_PROCESS_GROUP+NORMAL_PRIORITY_CLASS,
                    nil, nil, StartInfo, ProcInfo);
 { check to see if successful }
 if CreateOK then
  begin
    //may or may not be needed. Usually wait for child processes
   if Wait then
    WaitForSingleObject(ProcInfo.hProcess, INFINITE);
  end
 else
  begin
   ShowMessage('Unable to run '+ProgramName);
  end;

 CloseHandle(ProcInfo.hProcess);
 CloseHandle(ProcInfo.hThread);
end;

Edited: after reading your comments, I suggest that you look at this previous question


问:
RXJS throttletime operator is not working in Angular
I have a method that is making http calls to the server. this method is being called like 500 times and leading page to crash. I want to separate the calls and make a 200ms delay between calls. I thought of using throttletime operator but it it is not working.

```<code>testSubject: Subject<number> = new Subject<number>();

testMethod(id){
   for(let i = 0; i < 500; i++){
     this.testSubject.next(this.counter);
     this.testSubject.pipe(throttleTime(200)).subscribe(
        (data:any) =>{
           return this.addRow(groupId);
         }
        )
        this.counter++;
    }
}
</code>```

I expect the code above to work as follow:

counter gets incremented by 1

Subject.next() fires to update the subject with the new value

Adding the throttletime when subscribing to the testSubject. so it should make 200ms delay

答:
You can do something like this, you can use concatMap if you want to wait for the request to finish until you want to send the next one. Use range instead of the for loop to iterate 500 times.

range(1, 500).pipe(
     concatMap(() => {
     return this.yourHttpService.addRow(groupId).pipe(throttleTime(200));
    })
   )
   .subscribe(() => {
     console.log('HTTP successful requests');
   });
```

This will repeat HTTP requests after successful completion and 200ms delay if the request completes before 200ms.

Body:
I have a method that is making http calls to the server. this method is being called like 500 times and leading page to crash. I want to separate the calls and make a 200ms delay between calls. I thought of using throttletime operator but it it is not working.

testSubject: Subject<number> = new Subject<number>();

testMethod(id){
   for(let i = 0; i < 500; i++){
     this.testSubject.next(this.counter);
     this.testSubject.pipe(throttleTime(200)).subscribe(
        (data:any) =>{
           return this.addRow(groupId);
         }
        )
        this.counter++;
    }
}

I expect the code above to work as follow:

counter gets incremented by 1

Subject.next() fires to update the subject with the new value

Adding the throttletime when subscribing to the testSubject. so it should make 200ms delay

Body:
You can do something like this, you can use concatMap if you want to wait for the request to finish until you want to send the next one. Use range instead of the for loop to iterate 500 times.

range(1, 500).pipe(
     concatMap(() => {
     return this.yourHttpService.addRow(groupId).pipe(throttleTime(200));
    })
   )
   .subscribe(() => {
     console.log('HTTP successful requests');
   });

This will repeat HTTP requests after successful completion and 200ms delay if the request completes before 200ms.


问:
How to use pseudo-selectors in styleOverrides in MUI v5 Theming
The MUI(v5)'s documentation has given this example:

const theme = createTheme({
  components: {
    MuiButton: {
      styleOverrides: {
        root: {
          // How to use pseudo-class here?
          // I've tried this but it doesn't work:
          // "&:hover": {
          //   backgroundColor: "#000"
          //  }
          fontSize: '1rem',
        },
      },
    },
  },
});
```

However, what if I want to add CSS style to the Button when it's hovered (or other pseudo-class states)? Would those be possible with styleOverrides as well?

答:
Hi your code works perfectly in my repo.

```<code>const theme = createTheme({
  components: {
    MuiButton: {
      styleOverrides: {
        root: {
          '&:hover': {
            backgroundColor: '#000',
          },
          fontSize: '1rem',
        },
      },
    },
  },
});
</code>```

however if you are creating theme then you should also use theme.pallete and other theme options rather than directly adding css colors in button.

below is how I create custom mui button.

```<code>const myTheme = {
  ...
  components: {
    MuiButton: {
      styleOverrides: {
        root: ({ ownerState, theme }) => ({
          textTransform: 'capitalize',
          fontSize: '0.75rem',
          fontWeight: 500,
          padding: '10px 16px 10px 16px',
          // '&:hover': {
          //   backgroundColor: theme.palette.primary.dark,
          // },  // here worked as well
          ...(ownerState.variant === 'semicontained' && {
            color: theme.palette.primary.main,
            backgroundColor: theme.palette.primary.light,
          }),
        }),
      },
    },
  },
};

export default myTheme;
</code>```

Body:
The MUI(v5)'s documentation has given this example:

const theme = createTheme({
  components: {
    MuiButton: {
      styleOverrides: {
        root: {
          // How to use pseudo-class here?
          // I've tried this but it doesn't work:
          // "&:hover": {
          //   backgroundColor: "#000"
          //  }
          fontSize: '1rem',
        },
      },
    },
  },
});

However, what if I want to add CSS style to the Button when it's hovered (or other pseudo-class states)? Would those be possible with styleOverrides as well?

Body:
Hi your code works perfectly in my repo.

const theme = createTheme({
  components: {
    MuiButton: {
      styleOverrides: {
        root: {
          '&:hover': {
            backgroundColor: '#000',
          },
          fontSize: '1rem',
        },
      },
    },
  },
});

however if you are creating theme then you should also use theme.pallete and other theme options rather than directly adding css colors in button.

below is how I create custom mui button.

const myTheme = {
  ...
  components: {
    MuiButton: {
      styleOverrides: {
        root: ({ ownerState, theme }) => ({
          textTransform: 'capitalize',
          fontSize: '0.75rem',
          fontWeight: 500,
          padding: '10px 16px 10px 16px',
          // '&:hover': {
          //   backgroundColor: theme.palette.primary.dark,
          // },  // here worked as well
          ...(ownerState.variant === 'semicontained' && {
            color: theme.palette.primary.main,
            backgroundColor: theme.palette.primary.light,
          }),
        }),
      },
    },
  },
};

export default myTheme;