Rodhos Soft

備忘録を兼ねた技術的なメモです。Rofhos SoftではiOSアプリ開発を中心としてAndroid, Webサービス等の開発を承っております。まずはご相談下さい。

csvの加工

ちょっと進化した。

import csv
import pprint
import sys
import os
import glob

# usage
# python3 transErrorMessage.py

def replaceRet(txt: str):
    return txt.replace("\n", "\\n")

def wrapDQ(txt):
    return "\""+txt+"\""

surfix = "_SEMISELF"



def main(filepath):
    if len(filepath)>0:
        transFile(filepath)
        return
    
    l = glob.glob("./*.csv")
    for f in l:
        transFile(f)
        return
    

def transFile(filePath):
    translatedText = transTexts(filePath)
    filenameWithExt = os.path.basename(filePath)
    filename = os.path.splitext(filenameWithExt)[0]
    
    newfilepath = "./out/error_"+filename+".csv"

    # フォルダなければ作る
    file_path = os.path.dirname(newfilepath)
    if not os.path.exists(file_path):
        os.makedirs(file_path)

    with open(newfilepath,"w") as f:
        f.write(translatedText)



def transTexts(filePath):
    returnText = ""
    with open(filePath) as f:
        # print(f.read())

        reader = csv.reader(f)
        skip = True
        for row in reader:
            # print(row[0])
            if len(row)<=5:# row[5]までつかうので
                continue
            if skip:            
                if row[0] == "No":
                    skip = False
                    continue
                else:
                    continue

            message = wrapDQ(replaceRet(row[4]))
            message_SS = wrapDQ(replaceRet(row[5]))
            text = wrapDQ(row[1]) + " = " + message + ";"+"\n"
            text_ss = wrapDQ(row[1]+surfix) + " = " + message_SS + ";"+"\n"
            returnText = returnText + text + text_ss
    
    return returnText




# 実行部
filepath = ""
if len(sys.argv)>2:
    filepath = sys.argv[1]

main(filepath)

csvの加工

    import csv
    import pprint
    import sys

    # usage
    # python3 transErrorMessage.py a.csv 

    def replaceRet(txt:str):
        return txt.replace("\n","\\n")

    def wrapDQ(txt):
        return "\""+txt+"\""

    surfix = "_hoge"

    filename = sys.argv[1]

    with open("./"+filename) as f:
        # print(f.read())

        reader = csv.reader(f)
        skip = True;
        for row in reader:
            # print(row[0])
            if skip:
                if row[0] == "No":
                    skip = False
                    continue            
                else:
                    continue

            message = wrapDQ(replaceRet(row[4]))
            message_SS = wrapDQ(replaceRet(row[5]))
            print(wrapDQ(row[1]) + " = " + message +";")
            print(wrapDQ(row[1]+surfix) + " = " + message_SS +";")

hello express

expressをinstallしておく

npm install express

typeも

npm install @types/express
import express from "express";
var app = express();

app.get("/", (req, res) => {
    return res.send("Hello World!");    
});

app.listen(3001, () => {
    console.log("app listening on port 3001");
});

これでtscでトランスパイルし、nodeで実行、localhost:3001にアクセスする。

hello node

nodeのtypeを入れておく。

npm install @types/node
import * as http from "http"



let server:http.Server = http.createServer((req:http.IncomingMessage, res:http.ServerResponse) => {
    res.writeHead(200, {'Content-Type':'text/plain'});
    res.write("Hello World!");
    res.end();
});


server.listen(3001);

console.log("Server start at http://localhost:3001/");

これでlocalhost:3001でhello worldできる。

abc

バージョン確認

node -v
v10.16.0
npm -v
6.9.0

typescriptのコンフィグファイル作成

tsc --init

npm開始

npm init

typescript実験用にhello.ts作成

console.log("hello")

トランスパイル

tsc

試しに実行してみる。

node hello.js

jsの吐き出し先をdistフォルダに変更する。tsconfigで

    "outDir": "./dist",                        /* Redirect output structure to the directory. */

のように設定しておく。

文字横に画像

試行錯誤の結果次のようになった。

+ (NSAttributedString *)backSymbol {
    
    UIImage *image = [UIImage imageNamed:@"backbutton"];
    NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
    attachment.image = image;
    NSMutableAttributedString *ret = [[NSMutableAttributedString alloc] init];
    
    UIFont *font = [UIFont systemFontOfSize:17.0];
    CGSize size = CGSizeMake(font.lineHeight * image.size.width/image.size.height, font.lineHeight);
    
    CGFloat y = round(font.capHeight - size.height)/2;
    [attachment setBounds:CGRectMake(-size.width*1/4, y, size.width, size.height)];
    
    
    
    NSAttributedString *back = [NSMutableAttributedString attributedStringWithAttachment:attachment];
    
    [ret appendAttributedString:back];
//    NSMutableAttributedString *back = [[NSMutableAttributedString alloc] initWithString:@"<"];
    [ret addAttribute:NSFontAttributeName
                 value:[UIFont boldSystemFontOfSize:21.0]
                 range:NSMakeRange(0,back.length)];
    return ret;
}

参考

Swift5 UILabelに画像(UIImage)を表示する NSAttributedString NSTextAttachment - Qiita

A-Liaison BLOG: iOSのフォントのお話

delayする実験

#include <iostream>
#include "rx-includes.hpp"

class Man {
    public:
        Man();
        ~Man();

        void hello();

    private:
        int age;
        std::string name;

};

template <typename T>
class AbstBase {
    public:
    T hoge;
};

class FuncClass {
    public:
        FuncClass() : connectStateOb(std::shared_ptr<rxcpp::subjects::behavior<bool>>::make_shared(true)){

        };
        ~FuncClass(){}
        std::shared_ptr<rxcpp::subjects::behavior<bool>> connectStateOb;
        void poi();
        rxcpp::observable<std::string> connect();
        rxcpp::observable<std::string> disscconnect();
};

class Base : public AbstBase<Man>, public FuncClass
{
public:
    Base() : FuncClass(){};
    ~Base(){};
};

class Conc: Base {
    public:
        Conc(): Base(){

        };
        
        ~Conc(){
            std::cout << " ** deconstruction Conc **" << std::endl;
        };
        rxcpp::observable<std::string> rxtest();
        void log(std::string txt);
};
#include "man.hpp"
#include <chrono>

Man::Man(): name("hoge"), age(0) {

}

Man::~Man() {
    std::cout << " ** desconstructe Man **" << std::endl;
}

void Man::hello() {
    std::cout << " ** hello **" << std::endl;
}

void FuncClass::poi()
{
    std::cout << " ** poi **" << std::endl;
}

rxcpp::observable<std::string> FuncClass::connect() {
    rxcpp::observable<int> a = rxcpp::observable<>::just(0)
                                   .delay(std::chrono::milliseconds(1000));

    rxcpp::observable<std::string> b = a.flat_map([=](auto x) {
                  rxcpp::observable<std::string> c = rxcpp::observable<>::just<std::string>(std::string("event!"));
                  return c;
              }).as_dynamic();

    return b;
}

rxcpp::observable<std::string> FuncClass::disscconnect() {
    auto v = rxcpp::observable<>::interval(std::chrono::milliseconds(1000), rxcpp::observe_on_new_thread())
                 .map([=](long x) {
                     return std::to_string(x);
                 })
                 .take(2);
    return v;
}

void Conc::log(std::string txt) {
    std::cout << txt << std::endl;
}

rxcpp::observable<std::string> Conc::rxtest() {
    auto o = rxcpp::observable<>::just(10).as_dynamic();
    rxcpp::observable<std::string> s = o.flat_map([=](int x) {
                  return connect();
              })
                 .as_dynamic()
                 .flat_map([=](std::string c) {
                     std::cout << "==>" << c << std::endl;
                     log("log1");
                     return disscconnect();
                 })
                 .as_dynamic()
                 .flat_map([=](std::string d) {
                     log("log2");
                     log(d);
                     this->hoge.hello();
                     return rxcpp::observable<>::just(d);
                 })
                 .as_dynamic();

    return s;
}

操作を遅らせたりして動作を確認していた。

void rxtest2() {
    std::shared_ptr<Conc> conc = std::shared_ptr<Conc>::make_shared();
    rxcpp::observable<std::string> x =  conc->rxtest();
    auto l = x.subscribe([=](auto r) {
        std::cout << "** get event **" << std::endl;
        std::cout << r << std::endl;
    });

    conc.reset();

    std::async(std::launch::async, [l]() {
        usleep(5 * 1000 * 1000);
        std::cout << "** unsubscribe **" << std::endl;
        l.unsubscribe();

        

        usleep(5 * 1000 * 1000);
        std::cout << "** end **" << std::endl;

    });
}

色々やっているうちにコードが無駄に複雑化したがオブジェクトのデストラクタのタイミング等が少し理解できた。

分割コンパイル

hojo.hpp

int hello();

hojo.cpp

#include "hojo.hpp"

int hello() {
    return 1000;
}

hello.cpp

#include <iostream>
#include "hojo.hpp"

using namespace std;

int main(){
  cout << "Hello world." << endl;
  int x = hello();
  cout << x << endl;
  return 0;
}

というファイルをコンパイルしたいとする。 次のようなMakefileを作る。

Makefile

objs = hello.o hojo.o

CC = clang++

hello: $(objs)
    $(CC)  -o hello $(objs)

hello.o:hello.cpp
    $(CC) -c -o hello.o hello.cpp
hojo.o:hojo.cpp
    $(CC) -c -o hojo.o hojo.cpp

clean:
    rm -f $(objs)

これでmakeすればビルドできる。

CMakeで同様の事をする場合

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
project(hello)
add_executable(hello hello.cpp hojo.cpp)

を作り、

mkdir build
cd build
cmake ..
make

でビルドできる。

そのご 他のフォルダをインクルードした

message("hoge")
cmake_minimum_required(VERSION 3.1)
enable_language(CXX)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

project(hello)
include_directories(/Users/hoge/RxCpp-4.0.0/Rx/v2/src)
# set(CMAKE_MODULE_PATH "usr/local/rxcpp" ${CMAKE_MODULE_PATH})
message("INCLUDE_DIRECTORIES ${INCLUDE_DIRECTORIES}")
message("CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}")
# find_package(rxcpp)
add_executable(hello hello.cpp hojo.cpp)

最低限webpackを使う

node package.config

{
  "name": "hoge",
  "version": "1.0.0",
  "description": "hoge",
  "main": "index.js",
  "scripts": {
    "build": "webpack",
    "watch": "webpack -w",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "KatagiriSo",
  "license": "ISC",
  "dependencies": {
    "ts-loader": "^6.1.0",
    "typescript": "^3.6.3",
    "webpack": "^4.39.3",
    "webpack-cli": "^3.3.8"
  }
}

typescriptのtsconfig.json

{
  "compilerOptions": {
    /* Basic Options */
    "target": "es5",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
    "module": "es2015",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
    "lib": ["es2019", "dom"],                             /* Specify library files to be included in the compilation. */
    // "allowJs": true,                       /* Allow javascript files to be compiled. */
    // "checkJs": true,                       /* Report errors in .js files. */
    // "jsx": "preserve",                     /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
    // "declaration": true,                   /* Generates corresponding '.d.ts' file. */
    // "declarationMap": true,                /* Generates a sourcemap for each corresponding '.d.ts' file. */
    "sourceMap": true,                     /* Generates corresponding '.map' file. */
    // "outFile": "./",                       /* Concatenate and emit output to single file. */
    // "outDir": "./",                        /* Redirect output structure to the directory. */
    // "rootDir": "./",                       /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
    // "composite": true,                     /* Enable project compilation */
    // "removeComments": true,                /* Do not emit comments to output. */
    // "noEmit": true,                        /* Do not emit outputs. */
    // "importHelpers": true,                 /* Import emit helpers from 'tslib'. */
    // "downlevelIteration": true,            /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
    // "isolatedModules": true,               /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */

    /* Strict Type-Checking Options */
    "strict": true,                           /* Enable all strict type-checking options. */
    // "noImplicitAny": true,                 /* Raise error on expressions and declarations with an implied 'any' type. */
    // "strictNullChecks": true,              /* Enable strict null checks. */
    // "strictFunctionTypes": true,           /* Enable strict checking of function types. */
    // "strictPropertyInitialization": true,  /* Enable strict checking of property initialization in classes. */
    // "noImplicitThis": true,                /* Raise error on 'this' expressions with an implied 'any' type. */
    // "alwaysStrict": true,                  /* Parse in strict mode and emit "use strict" for each source file. */

    /* Additional Checks */
    // "noUnusedLocals": true,                /* Report errors on unused locals. */
    // "noUnusedParameters": true,            /* Report errors on unused parameters. */
    // "noImplicitReturns": true,             /* Report error when not all code paths in function return a value. */
    // "noFallthroughCasesInSwitch": true,    /* Report errors for fallthrough cases in switch statement. */

    /* Module Resolution Options */
    "moduleResolution": "node",            /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
    // "baseUrl": "./",                       /* Base directory to resolve non-absolute module names. */
    // "paths": {},                           /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
    // "rootDirs": [],                        /* List of root folders whose combined content represents the structure of the project at runtime. */
    // "typeRoots": [],                       /* List of folders to include type definitions from. */
    // "types": [],                           /* Type declaration files to be included in compilation. */
    // "allowSyntheticDefaultImports": true,  /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
    "esModuleInterop": true                   /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
    // "preserveSymlinks": true,              /* Do not resolve the real path of symlinks. */

    /* Source Map Options */
    // "sourceRoot": "",                      /* Specify the location where debugger should locate TypeScript files instead of source locations. */
    // "mapRoot": "",                         /* Specify the location where debugger should locate map files instead of generated locations. */
    // "inlineSourceMap": true,               /* Emit a single file with source maps instead of having a separate file. */
    // "inlineSources": true,                 /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */

    /* Experimental Options */
    // "experimentalDecorators": true,        /* Enables experimental support for ES7 decorators. */
    // "emitDecoratorMetadata": true,         /* Enables experimental support for emitting type metadata for decorators. */
  }
}

webpackの webpack.config.js

module.exports = {
    mode: "development",
    entry: "./src/main.ts",

    module: {
        rules: [
            {
                test: /\.ts$/,
                use: "ts-loader"
            }
        ]
    },
    resolve: {
        extensions: [".ts"]
    }
};

node for mobile調べ

GitHub - JaneaSystems/nodejs-mobile: Full-fledged Node.js on Android and iOS

AndroidはV8 JavaScript engineをつかう。
iOSは略

sampleがあるので
フレームワークをそのsampleに入れるだけで動く。
NodeRunnerというクラスがあるので、それにjsのソースのパスを食わせる。